diff --git a/include/sdbus-c++/Message.h b/include/sdbus-c++/Message.h index d2ed4a9..fcd3ebc 100644 --- a/include/sdbus-c++/Message.h +++ b/include/sdbus-c++/Message.h @@ -215,6 +215,7 @@ namespace sdbus { const char* getSender() const; const char* getPath() const; const char* getDestination() const; + uint64_t getCookie() const; // TODO: short docs in whole Message API std::pair peekType() const; bool isValid() const; @@ -296,6 +297,7 @@ namespace sdbus { public: MethodReply() = default; void send() const; + uint64_t getReplyCookie() const; }; class Signal : public Message diff --git a/src/Message.cpp b/src/Message.cpp index 63ae3fa..4ccf89a 100644 --- a/src/Message.cpp +++ b/src/Message.cpp @@ -640,6 +640,14 @@ const char* Message::getDestination() const return sd_bus_message_get_destination((sd_bus_message*)msg_); } +uint64_t Message::getCookie() const +{ + uint64_t cookie; + auto r = sd_bus_message_get_cookie((sd_bus_message*)msg_, &cookie); + SDBUS_THROW_ERROR_IF(r < 0, "Failed to get cookie", -r); + return cookie; +} + std::pair Message::peekType() const { char typeSignature{}; @@ -841,6 +849,14 @@ void MethodReply::send() const connection_->sendMessage((sd_bus_message*)msg_); } +uint64_t MethodReply::getReplyCookie() const +{ + uint64_t cookie; + auto r = sd_bus_message_get_reply_cookie((sd_bus_message*)msg_, &cookie); + SDBUS_THROW_ERROR_IF(r < 0, "Failed to get cookie", -r); + return cookie; +} + void Signal::send() const { connection_->sendMessage((sd_bus_message*)msg_); diff --git a/tests/integrationtests/DBusMethodsTests.cpp b/tests/integrationtests/DBusMethodsTests.cpp index 1422a9e..382b30c 100644 --- a/tests/integrationtests/DBusMethodsTests.cpp +++ b/tests/integrationtests/DBusMethodsTests.cpp @@ -286,6 +286,14 @@ TYPED_TEST(SdbusTestObject, CanAccessAssociatedMethodCallMessageInMethodCallHand ASSERT_THAT(this->m_adaptor->m_methodName, Eq("doOperation")); } +TYPED_TEST(SdbusTestObject, ProvidesSerialInMethodCallAndMethodReplyMessage) +{ + auto reply = this->m_proxy->doOperationOnBasicAPILevel(ANY_UNSIGNED_NUMBER); + + ASSERT_THAT(this->m_proxy->m_methodCallMsg->getCookie(), Gt(0)); + ASSERT_THAT(reply.getReplyCookie(), Eq(this->m_proxy->m_methodCallMsg->getCookie())); // Pairing method reply with method call message +} + TYPED_TEST(SdbusTestObject, CanAccessAssociatedMethodCallMessageInAsyncMethodCallHandler) { this->m_proxy->doOperationAsync(10); // This will save pointer to method call message on server side diff --git a/tests/integrationtests/TestFixture.h b/tests/integrationtests/TestFixture.h index 4901ea3..afab194 100644 --- a/tests/integrationtests/TestFixture.h +++ b/tests/integrationtests/TestFixture.h @@ -50,6 +50,8 @@ namespace sdbus { namespace test { +inline const uint32_t ANY_UNSIGNED_NUMBER{123}; + class BaseTestFixture : public ::testing::Test { public: diff --git a/tests/integrationtests/TestProxy.cpp b/tests/integrationtests/TestProxy.cpp index 3592f01..b829754 100644 --- a/tests/integrationtests/TestProxy.cpp +++ b/tests/integrationtests/TestProxy.cpp @@ -113,6 +113,16 @@ uint32_t TestProxy::doOperationWithTimeout(const std::chrono::microseconds &time return result; } +MethodReply TestProxy::doOperationOnBasicAPILevel(uint32_t param) +{ + auto methodCall = getProxy().createMethodCall(test::INTERFACE_NAME, MethodName{"doOperation"}); + methodCall << param; + + m_methodCallMsg = std::make_unique(methodCall); + + return getProxy().callMethod(methodCall); +} + sdbus::PendingAsyncCall TestProxy::doOperationClientSideAsync(uint32_t param) { return getProxy().callMethodAsync("doOperation") diff --git a/tests/integrationtests/TestProxy.h b/tests/integrationtests/TestProxy.h index 0ca9f61..7909fbd 100644 --- a/tests/integrationtests/TestProxy.h +++ b/tests/integrationtests/TestProxy.h @@ -95,6 +95,7 @@ protected: public: void installDoOperationClientSideAsyncReplyHandler(std::function err)> handler); uint32_t doOperationWithTimeout(const std::chrono::microseconds &timeout, uint32_t param); + MethodReply doOperationOnBasicAPILevel(uint32_t param); sdbus::PendingAsyncCall doOperationClientSideAsync(uint32_t param); [[nodiscard]] sdbus::Slot doOperationClientSideAsync(uint32_t param, sdbus::return_slot_t); std::future doOperationClientSideAsync(uint32_t param, with_future_t); @@ -121,6 +122,7 @@ public: // for tests std::function err)> m_DoOperationClientSideAsyncReplyHandler; std::function&, const std::vector&)> m_onPropertiesChangedHandler; + std::unique_ptr m_methodCallMsg; std::unique_ptr m_signalMsg; SignalName m_signalName; };