2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
8 #include "DBusMessage.h"
11 #include "settings/AdvancedSettings.h"
12 #include "utils/log.h"
14 CDBusMessage::CDBusMessage(const char *destination
, const char *object
, const char *interface
, const char *method
)
16 m_message
.reset(dbus_message_new_method_call(destination
, object
, interface
, method
));
19 // Fails only due to memory allocation failure
20 throw std::runtime_error("dbus_message_new_method_call");
24 CLog::Log(LOGDEBUG
, LOGDBUS
, "DBus: Creating message to {} on {} with interface {} and method {}",
25 destination
, object
, interface
, method
);
28 CDBusMessage::CDBusMessage(const std::string
& destination
, const std::string
& object
, const std::string
& interface
, const std::string
& method
)
29 : CDBusMessage(destination
.c_str(), object
.c_str(), interface
.c_str(), method
.c_str())
33 void DBusMessageDeleter::operator()(DBusMessage
* message
) const
35 dbus_message_unref(message
);
38 void CDBusMessage::AppendObjectPath(const char *object
)
40 AppendWithType(DBUS_TYPE_OBJECT_PATH
, &object
);
44 void CDBusMessage::AppendArgument
<bool>(const bool arg
)
46 // dbus_bool_t width might not match C++ bool width
47 dbus_bool_t convArg
= (arg
== true);
48 AppendWithType(DBUS_TYPE_BOOLEAN
, &convArg
);
52 void CDBusMessage::AppendArgument
<std::string
>(const std::string arg
)
54 AppendArgument(arg
.c_str());
57 void CDBusMessage::AppendArgument(const char **arrayString
, unsigned int length
)
61 if (!dbus_message_iter_open_container(&m_args
, DBUS_TYPE_ARRAY
, DBUS_TYPE_STRING_AS_STRING
, &sub
))
63 throw std::runtime_error("dbus_message_iter_open_container");
66 for (unsigned int i
= 0; i
< length
; i
++)
68 if (!dbus_message_iter_append_basic(&sub
, DBUS_TYPE_STRING
, &arrayString
[i
]))
70 throw std::runtime_error("dbus_message_iter_append_basic");
74 if (!dbus_message_iter_close_container(&m_args
, &sub
))
76 throw std::runtime_error("dbus_message_iter_close_container");
80 void CDBusMessage::AppendWithType(int type
, const void* value
)
83 if (!dbus_message_iter_append_basic(&m_args
, type
, value
))
85 throw std::runtime_error("dbus_message_iter_append_basic");
89 DBusMessageIter
* CDBusMessage::GetArgumentIter() {
94 DBusMessage
*CDBusMessage::SendSystem()
96 return Send(DBUS_BUS_SYSTEM
);
99 DBusMessage
*CDBusMessage::SendSession()
101 return Send(DBUS_BUS_SESSION
);
104 DBusMessage
*CDBusMessage::SendSystem(CDBusError
& error
)
106 return Send(DBUS_BUS_SYSTEM
, error
);
109 DBusMessage
*CDBusMessage::SendSession(CDBusError
& error
)
111 return Send(DBUS_BUS_SESSION
, error
);
114 bool CDBusMessage::SendAsyncSystem()
116 return SendAsync(DBUS_BUS_SYSTEM
);
119 bool CDBusMessage::SendAsyncSession()
121 return SendAsync(DBUS_BUS_SESSION
);
124 DBusMessage
*CDBusMessage::Send(DBusBusType type
)
128 if (!con
.Connect(type
))
131 DBusMessage
*returnMessage
= Send(con
, error
);
136 return returnMessage
;
139 DBusMessage
*CDBusMessage::Send(DBusBusType type
, CDBusError
& error
)
142 if (!con
.Connect(type
, error
))
145 DBusMessage
*returnMessage
= Send(con
, error
);
147 return returnMessage
;
150 bool CDBusMessage::SendAsync(DBusBusType type
)
153 if (!con
.Connect(type
))
156 return dbus_connection_send(con
, m_message
.get(), nullptr);
159 DBusMessage
*CDBusMessage::Send(DBusConnection
*con
, CDBusError
& error
)
161 m_reply
.reset(dbus_connection_send_with_reply_and_block(con
, m_message
.get(), -1, error
));
162 return m_reply
.get();
165 void CDBusMessage::PrepareArgument()
168 dbus_message_iter_init_append(m_message
.get(), &m_args
);
173 bool CDBusMessage::InitializeReplyIter(DBusMessageIter
* iter
)
177 throw std::logic_error("Cannot get reply arguments of message that does not have reply");
179 if (!dbus_message_iter_init(m_reply
.get(), iter
))
181 CLog::Log(LOGWARNING
, "Tried to obtain reply arguments from message that has zero arguments");
187 bool CDBusMessage::CheckTypeAndGetValue(DBusMessageIter
* iter
, int expectType
, void* dest
)
189 const int haveType
= dbus_message_iter_get_arg_type(iter
);
190 if (haveType
!= expectType
)
192 CLog::Log(LOGDEBUG
, "DBus argument type mismatch: expected {}, got {}", expectType
, haveType
);
196 dbus_message_iter_get_basic(iter
, dest
);