openthread-br  0.3.0-72c0388
dbus_object.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019, The OpenThread Authors.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * 3. Neither the name of the copyright holder nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
34 #ifndef OTBR_DBUS_DBUS_OBJECT_HPP_
35 #define OTBR_DBUS_DBUS_OBJECT_HPP_
36 
37 #ifndef OTBR_LOG_TAG
38 #define OTBR_LOG_TAG "DBUS"
39 #endif
40 
41 #include <functional>
42 #include <memory>
43 #include <string>
44 #include <unordered_map>
45 
46 #include <dbus/dbus.h>
47 
48 #include "common/code_utils.hpp"
49 #include "common/types.hpp"
55 
56 namespace otbr {
57 namespace DBus {
58 
63 class DBusObject : private NonCopyable
64 {
65 public:
66  using MethodHandlerType = std::function<void(DBusRequest &)>;
67 
68  using PropertyHandlerType = std::function<otError(DBusMessageIter &)>;
69 
77  DBusObject(DBusConnection *aConnection, const std::string &aObjectPath);
78 
88  virtual otbrError Init(void);
89 
98  void RegisterMethod(const std::string & aInterfaceName,
99  const std::string & aMethodName,
100  const MethodHandlerType &aHandler);
101 
110  virtual void RegisterGetPropertyHandler(const std::string & aInterfaceName,
111  const std::string & aPropertyName,
112  const PropertyHandlerType &aHandler);
113 
122  virtual void RegisterSetPropertyHandler(const std::string & aInterfaceName,
123  const std::string & aPropertyName,
124  const PropertyHandlerType &aHandler);
125 
137  template <typename... FieldTypes>
138  otbrError Signal(const std::string & aInterfaceName,
139  const std::string & aSignalName,
140  const std::tuple<FieldTypes...> &aArgs)
141  {
142  UniqueDBusMessage signalMsg = NewSignalMessage(aInterfaceName, aSignalName);
143  otbrError error = OTBR_ERROR_NONE;
144 
145  VerifyOrExit(signalMsg != nullptr, error = OTBR_ERROR_DBUS);
146  SuccessOrExit(error = otbr::DBus::TupleToDBusMessage(*signalMsg, aArgs));
147 
148  VerifyOrExit(dbus_connection_send(mConnection, signalMsg.get(), nullptr), error = OTBR_ERROR_DBUS);
149 
150  exit:
151  return error;
152  }
153 
165  template <typename ValueType>
166  otbrError SignalPropertyChanged(const std::string &aInterfaceName,
167  const std::string &aPropertyName,
168  const ValueType & aValue)
169  {
170  UniqueDBusMessage signalMsg = NewSignalMessage(DBUS_INTERFACE_PROPERTIES, DBUS_PROPERTIES_CHANGED_SIGNAL);
171  DBusMessageIter iter, subIter, dictEntryIter;
172  otbrError error = OTBR_ERROR_NONE;
173 
174  VerifyOrExit(signalMsg != nullptr, error = OTBR_ERROR_DBUS);
175  dbus_message_iter_init_append(signalMsg.get(), &iter);
176 
177  // interface_name
178  VerifyOrExit(DBusMessageEncode(&iter, aInterfaceName) == OTBR_ERROR_NONE, error = OTBR_ERROR_DBUS);
179 
180  // changed_properties
181  VerifyOrExit(dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
182  "{" DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING "}",
183  &subIter),
184  error = OTBR_ERROR_DBUS);
185  VerifyOrExit(dbus_message_iter_open_container(&subIter, DBUS_TYPE_DICT_ENTRY, nullptr, &dictEntryIter),
186  error = OTBR_ERROR_DBUS);
187 
188  SuccessOrExit(error = DBusMessageEncode(&dictEntryIter, aPropertyName));
189  SuccessOrExit(error = DBusMessageEncodeToVariant(&dictEntryIter, aValue));
190 
191  VerifyOrExit(dbus_message_iter_close_container(&subIter, &dictEntryIter), error = OTBR_ERROR_DBUS);
192  VerifyOrExit(dbus_message_iter_close_container(&iter, &subIter), error = OTBR_ERROR_DBUS);
193 
194  // invalidated_properties
195  SuccessOrExit(error = DBusMessageEncode(&iter, std::vector<std::string>()));
196 
198  {
199  otbrLogDebug("Signal %s.%s", aInterfaceName.c_str(), aPropertyName.c_str());
200  DumpDBusMessage(*signalMsg);
201  }
202 
203  VerifyOrExit(dbus_connection_send(mConnection, signalMsg.get(), nullptr), error = OTBR_ERROR_DBUS);
204 
205  exit:
206  return error;
207  }
208 
213  virtual ~DBusObject(void);
214 
219  void Flush(void);
220 
221 private:
222  void GetAllPropertiesMethodHandler(DBusRequest &aRequest);
223  void GetPropertyMethodHandler(DBusRequest &aRequest);
224  void SetPropertyMethodHandler(DBusRequest &aRequest);
225 
226  static DBusHandlerResult sMessageHandler(DBusConnection *aConnection, DBusMessage *aMessage, void *aData);
227  DBusHandlerResult MessageHandler(DBusConnection *aConnection, DBusMessage *aMessage);
228 
229  UniqueDBusMessage NewSignalMessage(const std::string &aInterfaceName, const std::string &aSignalName);
230 
231  std::unordered_map<std::string, MethodHandlerType> mMethodHandlers;
232  std::unordered_map<std::string, std::unordered_map<std::string, PropertyHandlerType>> mGetPropertyHandlers;
233  std::unordered_map<std::string, PropertyHandlerType> mSetPropertyHandlers;
234  DBusConnection * mConnection;
235  std::string mObjectPath;
236 };
237 
238 } // namespace DBus
239 } // namespace otbr
240 
241 #endif // OTBR_DBUS_DBUS_SERVER_HPP_
otbr::DBus::DumpDBusMessage
void DumpDBusMessage(DBusMessage &aMessage)
Definition: dbus_message_dump.cpp:170
otbr::DBus::DBusObject::RegisterMethod
void RegisterMethod(const std::string &aInterfaceName, const std::string &aMethodName, const MethodHandlerType &aHandler)
Definition: dbus_object.cpp:74
dbus_message_helper.hpp
SuccessOrExit
#define SuccessOrExit(aStatus)
Definition: code_utils.hpp:73
OTBR_ERROR_DBUS
@ OTBR_ERROR_DBUS
DBus error.
Definition: types.hpp:75
otbr::DBus::DBusObject::Init
virtual otbrError Init(void)
Definition: dbus_object.cpp:52
otbr::DBus::DBusRequest
Definition: dbus_request.hpp:53
otbrLogGetLevel
otbrLogLevel otbrLogGetLevel(void)
Definition: logging.cpp:58
constants.hpp
otbr::DBus::DBusObject
Definition: dbus_object.hpp:63
otbr::DBus::DBusObject::Signal
otbrError Signal(const std::string &aInterfaceName, const std::string &aSignalName, const std::tuple< FieldTypes... > &aArgs)
Definition: dbus_object.hpp:138
dbus_resources.hpp
dbus_request.hpp
otbr::DBus::DBusMessageEncodeToVariant
otbrError DBusMessageEncodeToVariant(DBusMessageIter *aIter, const ValueType &aValue)
Definition: dbus_message_helper.hpp:713
otbr::DBus::DBusObject::Flush
void Flush(void)
Definition: dbus_object.cpp:264
code_utils.hpp
otbr::DBus::DBusObject::~DBusObject
virtual ~DBusObject(void)
Definition: dbus_object.cpp:255
otbr::DBus::DBusObject::RegisterGetPropertyHandler
virtual void RegisterGetPropertyHandler(const std::string &aInterfaceName, const std::string &aPropertyName, const PropertyHandlerType &aHandler)
Definition: dbus_object.cpp:84
otbrLogDebug
#define otbrLogDebug(...)
Definition: logging.hpp:246
otbr::DBus::DBusObject::RegisterSetPropertyHandler
virtual void RegisterSetPropertyHandler(const std::string &aInterfaceName, const std::string &aPropertyName, const PropertyHandlerType &aHandler)
Definition: dbus_object.cpp:91
dbus_message_dump.hpp
otbr::DBus::TupleToDBusMessage
otbrError TupleToDBusMessage(DBusMessage &aMessage, const std::tuple< FieldTypes... > &aValues)
Definition: dbus_message_helper.hpp:786
VerifyOrExit
#define VerifyOrExit(aCondition,...)
Definition: code_utils.hpp:110
OTBR_ERROR_NONE
@ OTBR_ERROR_NONE
No error.
Definition: types.hpp:72
otbrError
otbrError
Definition: types.hpp:70
OTBR_LOG_DEBUG
@ OTBR_LOG_DEBUG
Debug level messages.
Definition: logging.hpp:60
NonCopyable
Definition: code_utils.hpp:169
otbr::DBus::DBusObject::DBusObject
DBusObject(DBusConnection *aConnection, const std::string &aObjectPath)
Definition: dbus_object.cpp:46
otbr::DBus::DBusObject::SignalPropertyChanged
otbrError SignalPropertyChanged(const std::string &aInterfaceName, const std::string &aPropertyName, const ValueType &aValue)
Definition: dbus_object.hpp:166