Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / ot-br-posix / repo / src / dbus / server / dbus_object.hpp
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
29 /**
30  * @file
31  * This file includes definitions for a d-bus object.
32  */
33
34 #ifndef OTBR_DBUS_DBUS_OBJECT_HPP_
35 #define OTBR_DBUS_DBUS_OBJECT_HPP_
36
37 #include <functional>
38 #include <memory>
39 #include <string>
40 #include <unordered_map>
41
42 #include <dbus/dbus.h>
43
44 #include "common/code_utils.hpp"
45 #include "common/types.hpp"
46 #include "dbus/common/constants.hpp"
47 #include "dbus/common/dbus_message_dump.hpp"
48 #include "dbus/common/dbus_message_helper.hpp"
49 #include "dbus/common/dbus_resources.hpp"
50 #include "dbus/server/dbus_request.hpp"
51
52 namespace otbr {
53 namespace DBus {
54
55 /**
56  * This class is a base class for implementing a d-bus object.
57  *
58  */
59 class DBusObject
60 {
61 public:
62     using MethodHandlerType = std::function<void(DBusRequest &)>;
63
64     using PropertyHandlerType = std::function<otError(DBusMessageIter &)>;
65
66     /**
67      * The constructor of a d-bus object.
68      *
69      * @param[in]   aConnection   The dbus-connection the object bounds to.
70      * @param[in]   aObjectPath   The path of the object.
71      *
72      */
73     DBusObject(DBusConnection *aConnection, const std::string &aObjectPath);
74
75     /**
76      * This method initializes the d-bus object.
77      *
78      * This method will register the object to the d-bus library.
79      *
80      * @retval  OTBR_ERROR_NONE   Successfully registered the object.
81      * @retval  OTBR_ERROR_DBUS   Failed to ragister an object.
82      *
83      */
84     virtual otbrError Init(void);
85
86     /**
87      * This method registers the method handler.
88      *
89      * @param[in]   aInterfaceName    The interface name.
90      * @param[in]   aMethodName       The method name.
91      * @param[in]   aHandler          The method handler.
92      *
93      */
94     void RegisterMethod(const std::string &      aInterfaceName,
95                         const std::string &      aMethodName,
96                         const MethodHandlerType &aHandler);
97
98     /**
99      * This method registers the get handler for a property.
100      *
101      * @param[in]   aInterfaceName    The interface name.
102      * @param[in]   aMethodName       The method name.
103      * @param[in]   aHandler          The method handler.
104      *
105      */
106     void RegisterGetPropertyHandler(const std::string &        aInterfaceName,
107                                     const std::string &        aMethodName,
108                                     const PropertyHandlerType &aHandler);
109
110     /**
111      * This method registers the set handler for a property.
112      *
113      * @param[in]   aInterfaceName    The interface name.
114      * @param[in]   aMethodName       The method name.
115      * @param[in]   aHandler          The method handler.
116      *
117      */
118     void RegisterSetPropertyHandler(const std::string &        aInterfaceName,
119                                     const std::string &        aPropertyName,
120                                     const PropertyHandlerType &aHandler);
121
122     /**
123      * This method sends a signal.
124      *
125      * @param[in]   aInterfaceName    The interface name.
126      * @param[in]   aSignalName       The signal name.
127      * @param[in]   aArgs             The tuple to be encoded into the signal.
128      *
129      * @retval OTBR_ERROR_NONE  Signal successfully sent.
130      * @retval OTBR_ERROR_DBUS  Failed to send the signal.
131      *
132      */
133     template <typename... FieldTypes>
134     otbrError Signal(const std::string &              aInterfaceName,
135                      const std::string &              aSignalName,
136                      const std::tuple<FieldTypes...> &aArgs)
137     {
138         UniqueDBusMessage signalMsg{
139             dbus_message_new_signal(mObjectPath.c_str(), aInterfaceName.c_str(), aSignalName.c_str())};
140         otbrError error = OTBR_ERROR_NONE;
141
142         VerifyOrExit(signalMsg != nullptr, error = OTBR_ERROR_DBUS);
143         VerifyOrExit(error = otbr::DBus::TupleToDBusMessage(*signalMsg, aArgs));
144
145         VerifyOrExit(dbus_connection_send(mConnection, signalMsg.get(), nullptr), error = OTBR_ERROR_DBUS);
146
147     exit:
148         return error;
149     }
150
151     /**
152      * This method sends a property changed signal.
153      *
154      * @param[in]   aInterfaceName    The interface name.
155      * @param[in]   aPropertyName     The property name.
156      * @param[in]   aValue            New value of the property.
157      *
158      * @retval OTBR_ERROR_NONE  Signal successfully sent.
159      * @retval OTBR_ERROR_DBUS  Failed to send the signal.
160      *
161      */
162     template <typename ValueType>
163     otbrError SignalPropertyChanged(const std::string &aInterfaceName,
164                                     const std::string &aPropertyName,
165                                     const ValueType &  aValue)
166     {
167         UniqueDBusMessage signalMsg{
168             dbus_message_new_signal(mObjectPath.c_str(), DBUS_INTERFACE_PROPERTIES, DBUS_PROPERTIES_CHANGED_SIGNAL)};
169         DBusMessageIter iter, subIter, dictEntryIter;
170         otbrError       error = OTBR_ERROR_NONE;
171
172         VerifyOrExit(signalMsg != nullptr, error = OTBR_ERROR_DBUS);
173         dbus_message_iter_init_append(signalMsg.get(), &iter);
174
175         // interface_name
176         VerifyOrExit(DBusMessageEncode(&iter, aInterfaceName) == OTBR_ERROR_NONE, error = OTBR_ERROR_DBUS);
177
178         // changed_properties
179         VerifyOrExit(dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
180                                                       "{" DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING "}",
181                                                       &subIter),
182                      error = OTBR_ERROR_DBUS);
183         VerifyOrExit(dbus_message_iter_open_container(&subIter, DBUS_TYPE_DICT_ENTRY, nullptr, &dictEntryIter),
184                      error = OTBR_ERROR_DBUS);
185
186         SuccessOrExit(error = DBusMessageEncode(&dictEntryIter, aPropertyName));
187         SuccessOrExit(error = DBusMessageEncodeToVariant(&dictEntryIter, aValue));
188
189         VerifyOrExit(dbus_message_iter_close_container(&subIter, &dictEntryIter), error = OTBR_ERROR_DBUS);
190         VerifyOrExit(dbus_message_iter_close_container(&iter, &subIter), error = OTBR_ERROR_DBUS);
191
192         // invalidated_properties
193         SuccessOrExit(error = DBusMessageEncode(&iter, std::vector<std::string>()));
194
195         if (otbrLogGetLevel() >= OTBR_LOG_DEBUG)
196         {
197             otbrLog(OTBR_LOG_DEBUG, "Signal %s.%s", aInterfaceName.c_str(), aPropertyName.c_str());
198             DumpDBusMessage(*signalMsg);
199         }
200
201         VerifyOrExit(dbus_connection_send(mConnection, signalMsg.get(), nullptr), error = OTBR_ERROR_DBUS);
202
203     exit:
204         return error;
205     }
206
207     /**
208      * The destructor of a d-bus object.
209      *
210      */
211     virtual ~DBusObject(void);
212
213 private:
214     void GetAllPropertiesMethodHandler(DBusRequest &aRequest);
215
216     void GetPropertyMethodHandler(DBusRequest &aRequest);
217
218     void SetPropertyMethodHandler(DBusRequest &aRequest);
219
220     static DBusHandlerResult sMessageHandler(DBusConnection *aConnection, DBusMessage *aMessage, void *aData);
221     DBusHandlerResult        MessageHandler(DBusConnection *aConnection, DBusMessage *aMessage);
222
223     std::unordered_map<std::string, MethodHandlerType>                                    mMethodHandlers;
224     std::unordered_map<std::string, std::unordered_map<std::string, PropertyHandlerType>> mGetPropertyHandlers;
225     std::unordered_map<std::string, PropertyHandlerType>                                  mSetPropertyHandlers;
226     DBusConnection *                                                                      mConnection;
227     std::string                                                                           mObjectPath;
228 };
229
230 } // namespace DBus
231 } // namespace otbr
232
233 #endif // OTBR_DBUS_DBUS_SERVER_HPP_