diff --git a/raven/includes/serialization/deserialization_impl.hpp b/raven/includes/serialization/deserialization_impl.hpp index f71d93a..e70e191 100644 --- a/raven/includes/serialization/deserialization_impl.hpp +++ b/raven/includes/serialization/deserialization_impl.hpp @@ -348,4 +348,30 @@ deserialize(rvn::SubscribeErrorMessage& subscribeErrorMessage, ConstSpan& span, return deserializedBytes; } +template +static inline deserialize_return_t +deserialize(rvn::SubscribeUpdateMessage& subscribeUpdateMessage, ConstSpan& span, NetworkEndian = network_endian) +{ + std::uint64_t deserializedBytes = 0; + + deserializedBytes += + deserialize(subscribeUpdateMessage.requestId_, span); + + deserializedBytes += + deserialize(subscribeUpdateMessage.startLocation_.group_.get(), span); + deserializedBytes += + deserialize(subscribeUpdateMessage.startLocation_.object_.get(), span); + + deserializedBytes += + deserialize(subscribeUpdateMessage.endGroup_, span); + deserializedBytes += + deserialize_trivial(subscribeUpdateMessage.subscriberPriority_, span); + deserializedBytes += + deserialize_trivial(subscribeUpdateMessage.forward_, span); + + deserializedBytes += deserialize_params(subscribeUpdateMessage.parameters_, span); + + return deserializedBytes; +} + } // namespace rvn::serialization::detail diff --git a/raven/includes/serialization/messages.hpp b/raven/includes/serialization/messages.hpp index 56f40e0..c83f9bf 100644 --- a/raven/includes/serialization/messages.hpp +++ b/raven/includes/serialization/messages.hpp @@ -369,14 +369,44 @@ struct GoAwayMessage Subscribe Parameters (..) ... } */ -struct SubscribeUpdateMessage +struct SubscribeUpdateMessage : public ControlMessageBase { - iType subscribeId; - iType trackAlias; - iType group; - iType object; - // iType numberOfParameters; - std::vector params; + std::uint64_t requestId_; + GroupObjectPair startLocation_; + std::uint64_t endGroup_; + std::uint8_t subscriberPriority_; + std::uint8_t forward_; + std::vector parameters_; + + SubscribeUpdateMessage() : ControlMessageBase(MoQtMessageType::SUBSCRIBE_UPDATE) + { + } + + bool operator==(const SubscribeUpdateMessage& rhs) const + { + bool isEqual = true; + + isEqual &= requestId_ == rhs.requestId_; + isEqual &= endGroup_ == rhs.endGroup_; + isEqual &= subscriberPriority_ == rhs.subscriberPriority_; + isEqual &= forward_== rhs.forward_; + isEqual &= parameters_ == rhs.parameters_; + isEqual &= startLocation_ == rhs.startLocation_; + + return isEqual; + } + + friend inline std::ostream& operator<<(std::ostream& os, const SubscribeUpdateMessage& msg) + { + os << "RequestId: " << msg.requestId_ + << " Location: " << std::to_string(msg.startLocation_.group_.get()) + " " + std::to_string(msg.startLocation_.object_.get()) + << " EndGroup: " << msg.endGroup_ << " SubscriberPriority: " << msg.subscriberPriority_ + << " Forward: " << msg.forward_ + << " Parameters: "; + for (const auto& parameter : msg.parameters_) + os << parameter; + return os; + } }; /* diff --git a/raven/includes/serialization/serialization_impl.hpp b/raven/includes/serialization/serialization_impl.hpp index ccee361..eacb14f 100644 --- a/raven/includes/serialization/serialization_impl.hpp +++ b/raven/includes/serialization/serialization_impl.hpp @@ -143,6 +143,7 @@ template serialize_return_t serialize(ds::chunk& c, const StreamHeaderSubgroupObject& msg); serialize_return_t serialize(ds::chunk& c, const rvn::SubscribeErrorMessage& subscribeErrorMessage); serialize_return_t serialize(ds::chunk& c, const rvn::BatchSubscribeMessage& batchSubscribeMessage); + serialize_return_t serialize(ds::chunk& c, const rvn::SubscribeUpdateMessage& subscribeUpdateMessage); /////////////////////////////////////////////////////////////////////////////////////////////// // clang-format on } // namespace rvn::serialization::detail diff --git a/raven/src/serialization_impl.cpp b/raven/src/serialization_impl.cpp index 4c07fe0..b8b0f89 100644 --- a/raven/src/serialization_impl.cpp +++ b/raven/src/serialization_impl.cpp @@ -306,4 +306,37 @@ serialize(ds::chunk& c, const rvn::BatchSubscribeMessage& batchSubscribeMessage) return headerLen + msgLen; } + +serialize_return_t +serialize(ds::chunk& c, const rvn::SubscribeUpdateMessage& subscribeUpdateMessage) +{ + std::uint64_t msgLen = 0; + { + msgLen += mock_serialize(subscribeUpdateMessage.requestId_); + msgLen += mock_serialize(subscribeUpdateMessage.startLocation_.group_.get()); + msgLen += mock_serialize(subscribeUpdateMessage.startLocation_.object_.get()); + msgLen += mock_serialize(subscribeUpdateMessage.endGroup_); + msgLen += mock_serialize(subscribeUpdateMessage.subscriberPriority_); + msgLen += mock_serialize(subscribeUpdateMessage.forward_); + msgLen += mock_serialize(subscribeUpdateMessage.parameters_.size()); + for (const auto& parameter : subscribeUpdateMessage.parameters_) + msgLen += mock_serialize(parameter); + } + + std::uint64_t headerLen = 0; + headerLen += + serialize(c, utils::to_underlying(MoQtMessageType::SUBSCRIBE_UPDATE)); + headerLen += serialize(c, msgLen); + + serialize(c, subscribeUpdateMessage.requestId_); + serialize(c, subscribeUpdateMessage.startLocation_.group_.get()); + serialize(c, subscribeUpdateMessage.startLocation_.object_.get()); + serialize(c, subscribeUpdateMessage.endGroup_); + serialize(c, subscribeUpdateMessage.subscriberPriority_); + serialize(c, subscribeUpdateMessage.forward_); + serialize(c, subscribeUpdateMessage.parameters_.size()); + for (const auto& parameter : subscribeUpdateMessage.parameters_) + serialize(c, parameter); + return headerLen + msgLen; +} } // namespace rvn::serialization::detail diff --git a/tests/serialization/CMakeLists.txt b/tests/serialization/CMakeLists.txt index 1df850c..c494c5b 100644 --- a/tests/serialization/CMakeLists.txt +++ b/tests/serialization/CMakeLists.txt @@ -5,3 +5,4 @@ add_raven_test(serialize_server_setup_message.cpp) add_raven_test(serialize_subscribe_message.cpp) add_raven_test(serialize_subscribe_error_message.cpp) add_raven_test(serialize_batch_subscribe_message.cpp) +add_raven_test(serialize_subscribe_update_message.cpp) diff --git a/tests/serialization/serialize_subscribe_update_message.cpp b/tests/serialization/serialize_subscribe_update_message.cpp new file mode 100644 index 0000000..30efe42 --- /dev/null +++ b/tests/serialization/serialize_subscribe_update_message.cpp @@ -0,0 +1,88 @@ +#include "test_serialization_utils.hpp" +#include +#include +#include +#include +#include +#include +#include + +using namespace rvn; +using namespace rvn::serialization; + +void test_serialize_subscribe_error() +{ + SubscribeUpdateMessage msg; + ds::chunk c; + msg.requestId_ = 0x12345678; + GroupId group(0x87654321); + ObjectId object(0x11111111); + msg.startLocation_.group_ = group; + msg.startLocation_.object_ = object; + msg.endGroup_ = 0; + msg.subscriberPriority_ = 255; + msg.forward_ = 100; + Parameter param; + msg.parameters_.push_back(param); + + serialization::detail::serialize(c, msg); + + // clang-format off + /* + 00000010 00011000 10010010 00110100 01010110 01111000 11000000 00000000 00000000 00000000 10000111 01100101 01000011 00100001 + [msg type 0x02] [msg len 18] [requestId 0x12345678] [groupId 0x87654321] + + 10010001 00010001 00010001 00010001 00000000 11111111 01100100 00000001 00000011 + [objectId 0x11111111] [endGroup 0] [subscriberPriority 255] [forward 100] [Number of Parameters 1] [Parameter Type 0x03] + + 00000001 00000000 + [Parameter Length] [Timeout 0] + + */ + std::string expectedSerializationString = "00000010 00011000 10010010 00110100 01010110 01111000 11000000 00000000 00000000 00000000 10000111 01100101 01000011 00100001 10010001 00010001 00010001 00010001 00000000 11111111 01100100 00000001 00000011 00000001 00000000"; + // // clang-format on + auto expectedSerialization = binary_string_to_vector(expectedSerializationString); + + utils::ASSERT_LOG_THROW(c.size() == expectedSerialization.size(), "Size mismatch\n", + "Expected size: ", expectedSerialization.size(), + "\n", "Actual size: ", c.size(), "\n"); + for (std::size_t i = 0; i < c.size(); i++) + utils::ASSERT_LOG_THROW(c[i] == expectedSerialization[i], "Mismatch at index: ", i, + "\n", "Expected: ", int(expectedSerialization[i]), + "\n", "Actual: ", int(c[i]), "\n"); + + ds::ChunkSpan span(c); + + ControlMessageHeader header; + serialization::detail::deserialize(header, span); + + utils::ASSERT_LOG_THROW(header.messageType_ == MoQtMessageType::SUBSCRIBE_UPDATE, + "Message type mismatch\n", "Expected: ", + utils::to_underlying(MoQtMessageType::SUBSCRIBE_UPDATE), "\n", + "Actual: ", utils::to_underlying(header.messageType_), "\n"); + + SubscribeUpdateMessage deserializedMsg; + serialization::detail::deserialize(deserializedMsg, span); + + std::cout << "Deserialization Succesfull !!" << std::endl; + utils::ASSERT_LOG_THROW(msg == deserializedMsg, "Deserialization failed\n", + "Expected: ", msg, "\n", "Actual: ", deserializedMsg, "\n"); +} + +void tests() +{ + try + { + test_serialize_subscribe_error(); + } + catch (const std::exception& e) + { + std::cerr << "test failed\n"; + std::cerr << e.what() << '\n'; + } +} +int main() +{ + tests(); + return 0; +} \ No newline at end of file