feat: add cookie-related API to Message (#491)

Add `Message::getCookie()` and `MethodReply::getReplyCookie()` functions, based on underlying sd-bus cookie functions. They can be useful when pairing method call messages and method call reply messages.

---------

Co-authored-by: Dylan Howey <dylan.howey@evgo.com>
Co-authored-by: Stanislav Angelovič <stanislav.angelovic@protonmail.com>
This commit is contained in:
Dylan Howey
2025-05-05 01:04:20 -05:00
committed by GitHub
parent 4389ea39bf
commit 6212b12159
6 changed files with 40 additions and 0 deletions

View File

@ -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<char, const char*> 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

View File

@ -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<char, const char*> 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_);

View File

@ -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

View File

@ -50,6 +50,8 @@
namespace sdbus { namespace test {
inline const uint32_t ANY_UNSIGNED_NUMBER{123};
class BaseTestFixture : public ::testing::Test
{
public:

View File

@ -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>(methodCall);
return getProxy().callMethod(methodCall);
}
sdbus::PendingAsyncCall TestProxy::doOperationClientSideAsync(uint32_t param)
{
return getProxy().callMethodAsync("doOperation")

View File

@ -95,6 +95,7 @@ protected:
public:
void installDoOperationClientSideAsyncReplyHandler(std::function<void(uint32_t res, std::optional<sdbus::Error> 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<uint32_t> doOperationClientSideAsync(uint32_t param, with_future_t);
@ -121,6 +122,7 @@ public: // for tests
std::function<void(uint32_t res, std::optional<sdbus::Error> err)> m_DoOperationClientSideAsyncReplyHandler;
std::function<void(const sdbus::InterfaceName&, const std::map<PropertyName, sdbus::Variant>&, const std::vector<PropertyName>&)> m_onPropertiesChangedHandler;
std::unique_ptr<const MethodCall> m_methodCallMsg;
std::unique_ptr<const Message> m_signalMsg;
SignalName m_signalName;
};