xref: /aosp_15_r20/external/ot-br-posix/src/dbus/server/dbus_object.hpp (revision 4a64e381480ef79f0532b2421e44e6ee336b8e0d)
1*4a64e381SAndroid Build Coastguard Worker /*
2*4a64e381SAndroid Build Coastguard Worker  *    Copyright (c) 2019, The OpenThread Authors.
3*4a64e381SAndroid Build Coastguard Worker  *    All rights reserved.
4*4a64e381SAndroid Build Coastguard Worker  *
5*4a64e381SAndroid Build Coastguard Worker  *    Redistribution and use in source and binary forms, with or without
6*4a64e381SAndroid Build Coastguard Worker  *    modification, are permitted provided that the following conditions are met:
7*4a64e381SAndroid Build Coastguard Worker  *    1. Redistributions of source code must retain the above copyright
8*4a64e381SAndroid Build Coastguard Worker  *       notice, this list of conditions and the following disclaimer.
9*4a64e381SAndroid Build Coastguard Worker  *    2. Redistributions in binary form must reproduce the above copyright
10*4a64e381SAndroid Build Coastguard Worker  *       notice, this list of conditions and the following disclaimer in the
11*4a64e381SAndroid Build Coastguard Worker  *       documentation and/or other materials provided with the distribution.
12*4a64e381SAndroid Build Coastguard Worker  *    3. Neither the name of the copyright holder nor the
13*4a64e381SAndroid Build Coastguard Worker  *       names of its contributors may be used to endorse or promote products
14*4a64e381SAndroid Build Coastguard Worker  *       derived from this software without specific prior written permission.
15*4a64e381SAndroid Build Coastguard Worker  *
16*4a64e381SAndroid Build Coastguard Worker  *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17*4a64e381SAndroid Build Coastguard Worker  *    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*4a64e381SAndroid Build Coastguard Worker  *    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*4a64e381SAndroid Build Coastguard Worker  *    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20*4a64e381SAndroid Build Coastguard Worker  *    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*4a64e381SAndroid Build Coastguard Worker  *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*4a64e381SAndroid Build Coastguard Worker  *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*4a64e381SAndroid Build Coastguard Worker  *    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*4a64e381SAndroid Build Coastguard Worker  *    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*4a64e381SAndroid Build Coastguard Worker  *    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*4a64e381SAndroid Build Coastguard Worker  *    POSSIBILITY OF SUCH DAMAGE.
27*4a64e381SAndroid Build Coastguard Worker  */
28*4a64e381SAndroid Build Coastguard Worker 
29*4a64e381SAndroid Build Coastguard Worker /**
30*4a64e381SAndroid Build Coastguard Worker  * @file
31*4a64e381SAndroid Build Coastguard Worker  * This file includes definitions for a d-bus object.
32*4a64e381SAndroid Build Coastguard Worker  */
33*4a64e381SAndroid Build Coastguard Worker 
34*4a64e381SAndroid Build Coastguard Worker #ifndef OTBR_DBUS_DBUS_OBJECT_HPP_
35*4a64e381SAndroid Build Coastguard Worker #define OTBR_DBUS_DBUS_OBJECT_HPP_
36*4a64e381SAndroid Build Coastguard Worker 
37*4a64e381SAndroid Build Coastguard Worker #include "openthread-br/config.h"
38*4a64e381SAndroid Build Coastguard Worker 
39*4a64e381SAndroid Build Coastguard Worker #ifndef OTBR_LOG_TAG
40*4a64e381SAndroid Build Coastguard Worker #define OTBR_LOG_TAG "DBUS"
41*4a64e381SAndroid Build Coastguard Worker #endif
42*4a64e381SAndroid Build Coastguard Worker 
43*4a64e381SAndroid Build Coastguard Worker #include <functional>
44*4a64e381SAndroid Build Coastguard Worker #include <memory>
45*4a64e381SAndroid Build Coastguard Worker #include <string>
46*4a64e381SAndroid Build Coastguard Worker #include <unordered_map>
47*4a64e381SAndroid Build Coastguard Worker 
48*4a64e381SAndroid Build Coastguard Worker #include <dbus/dbus.h>
49*4a64e381SAndroid Build Coastguard Worker 
50*4a64e381SAndroid Build Coastguard Worker #include "common/code_utils.hpp"
51*4a64e381SAndroid Build Coastguard Worker #include "common/types.hpp"
52*4a64e381SAndroid Build Coastguard Worker #include "dbus/common/constants.hpp"
53*4a64e381SAndroid Build Coastguard Worker #include "dbus/common/dbus_message_dump.hpp"
54*4a64e381SAndroid Build Coastguard Worker #include "dbus/common/dbus_message_helper.hpp"
55*4a64e381SAndroid Build Coastguard Worker #include "dbus/common/dbus_resources.hpp"
56*4a64e381SAndroid Build Coastguard Worker #include "dbus/server/dbus_request.hpp"
57*4a64e381SAndroid Build Coastguard Worker 
58*4a64e381SAndroid Build Coastguard Worker namespace otbr {
59*4a64e381SAndroid Build Coastguard Worker namespace DBus {
60*4a64e381SAndroid Build Coastguard Worker 
61*4a64e381SAndroid Build Coastguard Worker /**
62*4a64e381SAndroid Build Coastguard Worker  * This class is a base class for implementing a d-bus object.
63*4a64e381SAndroid Build Coastguard Worker  */
64*4a64e381SAndroid Build Coastguard Worker class DBusObject : private NonCopyable
65*4a64e381SAndroid Build Coastguard Worker {
66*4a64e381SAndroid Build Coastguard Worker public:
67*4a64e381SAndroid Build Coastguard Worker     using MethodHandlerType        = std::function<void(DBusRequest &)>;
68*4a64e381SAndroid Build Coastguard Worker     using AsyncPropertyHandlerType = std::function<void(DBusRequest &)>;
69*4a64e381SAndroid Build Coastguard Worker     using PropertyHandlerType      = std::function<otError(DBusMessageIter &)>;
70*4a64e381SAndroid Build Coastguard Worker 
71*4a64e381SAndroid Build Coastguard Worker     /**
72*4a64e381SAndroid Build Coastguard Worker      * The constructor of a d-bus object.
73*4a64e381SAndroid Build Coastguard Worker      *
74*4a64e381SAndroid Build Coastguard Worker      * @param[in] aConnection  The dbus-connection the object bounds to.
75*4a64e381SAndroid Build Coastguard Worker      * @param[in] aObjectPath  The path of the object.
76*4a64e381SAndroid Build Coastguard Worker      */
77*4a64e381SAndroid Build Coastguard Worker     DBusObject(DBusConnection *aConnection, const std::string &aObjectPath);
78*4a64e381SAndroid Build Coastguard Worker 
79*4a64e381SAndroid Build Coastguard Worker     /**
80*4a64e381SAndroid Build Coastguard Worker      * This method initializes the d-bus object.
81*4a64e381SAndroid Build Coastguard Worker      *
82*4a64e381SAndroid Build Coastguard Worker      * This method will register the object to the d-bus library.
83*4a64e381SAndroid Build Coastguard Worker      *
84*4a64e381SAndroid Build Coastguard Worker      * @retval OTBR_ERROR_NONE  Successfully registered the object.
85*4a64e381SAndroid Build Coastguard Worker      * @retval OTBR_ERROR_DBUS  Failed to ragister an object.
86*4a64e381SAndroid Build Coastguard Worker      */
87*4a64e381SAndroid Build Coastguard Worker     virtual otbrError Init(void);
88*4a64e381SAndroid Build Coastguard Worker 
89*4a64e381SAndroid Build Coastguard Worker     /**
90*4a64e381SAndroid Build Coastguard Worker      * This method registers the method handler.
91*4a64e381SAndroid Build Coastguard Worker      *
92*4a64e381SAndroid Build Coastguard Worker      * @param[in] aInterfaceName  The interface name.
93*4a64e381SAndroid Build Coastguard Worker      * @param[in] aMethodName     The method name.
94*4a64e381SAndroid Build Coastguard Worker      * @param[in] aHandler        The method handler.
95*4a64e381SAndroid Build Coastguard Worker      */
96*4a64e381SAndroid Build Coastguard Worker     void RegisterMethod(const std::string       &aInterfaceName,
97*4a64e381SAndroid Build Coastguard Worker                         const std::string       &aMethodName,
98*4a64e381SAndroid Build Coastguard Worker                         const MethodHandlerType &aHandler);
99*4a64e381SAndroid Build Coastguard Worker 
100*4a64e381SAndroid Build Coastguard Worker     /**
101*4a64e381SAndroid Build Coastguard Worker      * This method registers the get handler for a property.
102*4a64e381SAndroid Build Coastguard Worker      *
103*4a64e381SAndroid Build Coastguard Worker      * @param[in] aInterfaceName  The interface name.
104*4a64e381SAndroid Build Coastguard Worker      * @param[in] aPropertyName   The property name.
105*4a64e381SAndroid Build Coastguard Worker      * @param[in] aHandler        The method handler.
106*4a64e381SAndroid Build Coastguard Worker      */
107*4a64e381SAndroid Build Coastguard Worker     virtual void RegisterGetPropertyHandler(const std::string         &aInterfaceName,
108*4a64e381SAndroid Build Coastguard Worker                                             const std::string         &aPropertyName,
109*4a64e381SAndroid Build Coastguard Worker                                             const PropertyHandlerType &aHandler);
110*4a64e381SAndroid Build Coastguard Worker 
111*4a64e381SAndroid Build Coastguard Worker     /**
112*4a64e381SAndroid Build Coastguard Worker      * This method registers the set handler for a property.
113*4a64e381SAndroid Build Coastguard Worker      *
114*4a64e381SAndroid Build Coastguard Worker      * @param[in] aInterfaceName  The interface name.
115*4a64e381SAndroid Build Coastguard Worker      * @param[in] aPropertyName   The property name.
116*4a64e381SAndroid Build Coastguard Worker      * @param[in] aHandler        The method handler.
117*4a64e381SAndroid Build Coastguard Worker      */
118*4a64e381SAndroid Build Coastguard Worker     virtual void RegisterSetPropertyHandler(const std::string         &aInterfaceName,
119*4a64e381SAndroid Build Coastguard Worker                                             const std::string         &aPropertyName,
120*4a64e381SAndroid Build Coastguard Worker                                             const PropertyHandlerType &aHandler);
121*4a64e381SAndroid Build Coastguard Worker 
122*4a64e381SAndroid Build Coastguard Worker     /**
123*4a64e381SAndroid Build Coastguard Worker      * This method registers the async get handler for a property.
124*4a64e381SAndroid Build Coastguard Worker      *
125*4a64e381SAndroid Build Coastguard Worker      * @param[in] aInterfaceName  The interface name.
126*4a64e381SAndroid Build Coastguard Worker      * @param[in] aPropertyName   The property name.
127*4a64e381SAndroid Build Coastguard Worker      * @param[in] aHandler        The method handler.
128*4a64e381SAndroid Build Coastguard Worker      */
129*4a64e381SAndroid Build Coastguard Worker     virtual void RegisterAsyncGetPropertyHandler(const std::string              &aInterfaceName,
130*4a64e381SAndroid Build Coastguard Worker                                                  const std::string              &aPropertyName,
131*4a64e381SAndroid Build Coastguard Worker                                                  const AsyncPropertyHandlerType &aHandler);
132*4a64e381SAndroid Build Coastguard Worker 
133*4a64e381SAndroid Build Coastguard Worker     /**
134*4a64e381SAndroid Build Coastguard Worker      * This method sends a signal.
135*4a64e381SAndroid Build Coastguard Worker      *
136*4a64e381SAndroid Build Coastguard Worker      * @param[in] aInterfaceName  The interface name.
137*4a64e381SAndroid Build Coastguard Worker      * @param[in] aSignalName     The signal name.
138*4a64e381SAndroid Build Coastguard Worker      * @param[in] aArgs           The tuple to be encoded into the signal.
139*4a64e381SAndroid Build Coastguard Worker      *
140*4a64e381SAndroid Build Coastguard Worker      * @retval OTBR_ERROR_NONE  Signal successfully sent.
141*4a64e381SAndroid Build Coastguard Worker      * @retval OTBR_ERROR_DBUS  Failed to send the signal.
142*4a64e381SAndroid Build Coastguard Worker      */
143*4a64e381SAndroid Build Coastguard Worker     template <typename... FieldTypes>
Signal(const std::string & aInterfaceName,const std::string & aSignalName,const std::tuple<FieldTypes...> & aArgs)144*4a64e381SAndroid Build Coastguard Worker     otbrError Signal(const std::string               &aInterfaceName,
145*4a64e381SAndroid Build Coastguard Worker                      const std::string               &aSignalName,
146*4a64e381SAndroid Build Coastguard Worker                      const std::tuple<FieldTypes...> &aArgs)
147*4a64e381SAndroid Build Coastguard Worker     {
148*4a64e381SAndroid Build Coastguard Worker         UniqueDBusMessage signalMsg = NewSignalMessage(aInterfaceName, aSignalName);
149*4a64e381SAndroid Build Coastguard Worker         otbrError         error     = OTBR_ERROR_NONE;
150*4a64e381SAndroid Build Coastguard Worker 
151*4a64e381SAndroid Build Coastguard Worker         VerifyOrExit(signalMsg != nullptr, error = OTBR_ERROR_DBUS);
152*4a64e381SAndroid Build Coastguard Worker         SuccessOrExit(error = otbr::DBus::TupleToDBusMessage(*signalMsg, aArgs));
153*4a64e381SAndroid Build Coastguard Worker 
154*4a64e381SAndroid Build Coastguard Worker         VerifyOrExit(dbus_connection_send(mConnection, signalMsg.get(), nullptr), error = OTBR_ERROR_DBUS);
155*4a64e381SAndroid Build Coastguard Worker 
156*4a64e381SAndroid Build Coastguard Worker     exit:
157*4a64e381SAndroid Build Coastguard Worker         return error;
158*4a64e381SAndroid Build Coastguard Worker     }
159*4a64e381SAndroid Build Coastguard Worker 
160*4a64e381SAndroid Build Coastguard Worker     /**
161*4a64e381SAndroid Build Coastguard Worker      * This method sends a property changed signal.
162*4a64e381SAndroid Build Coastguard Worker      *
163*4a64e381SAndroid Build Coastguard Worker      * @param[in] aInterfaceName  The interface name.
164*4a64e381SAndroid Build Coastguard Worker      * @param[in] aPropertyName   The property name.
165*4a64e381SAndroid Build Coastguard Worker      * @param[in] aValue          New value of the property.
166*4a64e381SAndroid Build Coastguard Worker      *
167*4a64e381SAndroid Build Coastguard Worker      * @retval OTBR_ERROR_NONE  Signal successfully sent.
168*4a64e381SAndroid Build Coastguard Worker      * @retval OTBR_ERROR_DBUS  Failed to send the signal.
169*4a64e381SAndroid Build Coastguard Worker      */
170*4a64e381SAndroid Build Coastguard Worker     template <typename ValueType>
SignalPropertyChanged(const std::string & aInterfaceName,const std::string & aPropertyName,const ValueType & aValue)171*4a64e381SAndroid Build Coastguard Worker     otbrError SignalPropertyChanged(const std::string &aInterfaceName,
172*4a64e381SAndroid Build Coastguard Worker                                     const std::string &aPropertyName,
173*4a64e381SAndroid Build Coastguard Worker                                     const ValueType   &aValue)
174*4a64e381SAndroid Build Coastguard Worker     {
175*4a64e381SAndroid Build Coastguard Worker         UniqueDBusMessage signalMsg = NewSignalMessage(DBUS_INTERFACE_PROPERTIES, DBUS_PROPERTIES_CHANGED_SIGNAL);
176*4a64e381SAndroid Build Coastguard Worker         DBusMessageIter   iter, subIter, dictEntryIter;
177*4a64e381SAndroid Build Coastguard Worker         otbrError         error = OTBR_ERROR_NONE;
178*4a64e381SAndroid Build Coastguard Worker 
179*4a64e381SAndroid Build Coastguard Worker         VerifyOrExit(signalMsg != nullptr, error = OTBR_ERROR_DBUS);
180*4a64e381SAndroid Build Coastguard Worker         dbus_message_iter_init_append(signalMsg.get(), &iter);
181*4a64e381SAndroid Build Coastguard Worker 
182*4a64e381SAndroid Build Coastguard Worker         // interface_name
183*4a64e381SAndroid Build Coastguard Worker         VerifyOrExit(DBusMessageEncode(&iter, aInterfaceName) == OTBR_ERROR_NONE, error = OTBR_ERROR_DBUS);
184*4a64e381SAndroid Build Coastguard Worker 
185*4a64e381SAndroid Build Coastguard Worker         // changed_properties
186*4a64e381SAndroid Build Coastguard Worker         VerifyOrExit(dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
187*4a64e381SAndroid Build Coastguard Worker                                                       "{" DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING "}",
188*4a64e381SAndroid Build Coastguard Worker                                                       &subIter),
189*4a64e381SAndroid Build Coastguard Worker                      error = OTBR_ERROR_DBUS);
190*4a64e381SAndroid Build Coastguard Worker         VerifyOrExit(dbus_message_iter_open_container(&subIter, DBUS_TYPE_DICT_ENTRY, nullptr, &dictEntryIter),
191*4a64e381SAndroid Build Coastguard Worker                      error = OTBR_ERROR_DBUS);
192*4a64e381SAndroid Build Coastguard Worker 
193*4a64e381SAndroid Build Coastguard Worker         SuccessOrExit(error = DBusMessageEncode(&dictEntryIter, aPropertyName));
194*4a64e381SAndroid Build Coastguard Worker         SuccessOrExit(error = DBusMessageEncodeToVariant(&dictEntryIter, aValue));
195*4a64e381SAndroid Build Coastguard Worker 
196*4a64e381SAndroid Build Coastguard Worker         VerifyOrExit(dbus_message_iter_close_container(&subIter, &dictEntryIter), error = OTBR_ERROR_DBUS);
197*4a64e381SAndroid Build Coastguard Worker         VerifyOrExit(dbus_message_iter_close_container(&iter, &subIter), error = OTBR_ERROR_DBUS);
198*4a64e381SAndroid Build Coastguard Worker 
199*4a64e381SAndroid Build Coastguard Worker         // invalidated_properties
200*4a64e381SAndroid Build Coastguard Worker         SuccessOrExit(error = DBusMessageEncode(&iter, std::vector<std::string>()));
201*4a64e381SAndroid Build Coastguard Worker 
202*4a64e381SAndroid Build Coastguard Worker         if (otbrLogGetLevel() >= OTBR_LOG_DEBUG)
203*4a64e381SAndroid Build Coastguard Worker         {
204*4a64e381SAndroid Build Coastguard Worker             otbrLogDebug("Signal %s.%s", aInterfaceName.c_str(), aPropertyName.c_str());
205*4a64e381SAndroid Build Coastguard Worker             DumpDBusMessage(*signalMsg);
206*4a64e381SAndroid Build Coastguard Worker         }
207*4a64e381SAndroid Build Coastguard Worker 
208*4a64e381SAndroid Build Coastguard Worker         VerifyOrExit(dbus_connection_send(mConnection, signalMsg.get(), nullptr), error = OTBR_ERROR_DBUS);
209*4a64e381SAndroid Build Coastguard Worker 
210*4a64e381SAndroid Build Coastguard Worker     exit:
211*4a64e381SAndroid Build Coastguard Worker         return error;
212*4a64e381SAndroid Build Coastguard Worker     }
213*4a64e381SAndroid Build Coastguard Worker 
214*4a64e381SAndroid Build Coastguard Worker     /**
215*4a64e381SAndroid Build Coastguard Worker      * The destructor of a d-bus object.
216*4a64e381SAndroid Build Coastguard Worker      */
217*4a64e381SAndroid Build Coastguard Worker     virtual ~DBusObject(void);
218*4a64e381SAndroid Build Coastguard Worker 
219*4a64e381SAndroid Build Coastguard Worker     /**
220*4a64e381SAndroid Build Coastguard Worker      * Sends all outgoing messages, blocks until the message queue is empty.
221*4a64e381SAndroid Build Coastguard Worker      */
222*4a64e381SAndroid Build Coastguard Worker     void Flush(void);
223*4a64e381SAndroid Build Coastguard Worker 
224*4a64e381SAndroid Build Coastguard Worker protected:
225*4a64e381SAndroid Build Coastguard Worker     otbrError Initialize(bool aIsAsyncPropertyHandler);
226*4a64e381SAndroid Build Coastguard Worker 
227*4a64e381SAndroid Build Coastguard Worker private:
228*4a64e381SAndroid Build Coastguard Worker     void GetAllPropertiesMethodHandler(DBusRequest &aRequest);
229*4a64e381SAndroid Build Coastguard Worker     void GetPropertyMethodHandler(DBusRequest &aRequest);
230*4a64e381SAndroid Build Coastguard Worker     void SetPropertyMethodHandler(DBusRequest &aRequest);
231*4a64e381SAndroid Build Coastguard Worker     void AsyncGetPropertyMethodHandler(DBusRequest &aRequest);
232*4a64e381SAndroid Build Coastguard Worker 
233*4a64e381SAndroid Build Coastguard Worker     static DBusHandlerResult sMessageHandler(DBusConnection *aConnection, DBusMessage *aMessage, void *aData);
234*4a64e381SAndroid Build Coastguard Worker     DBusHandlerResult        MessageHandler(DBusConnection *aConnection, DBusMessage *aMessage);
235*4a64e381SAndroid Build Coastguard Worker 
236*4a64e381SAndroid Build Coastguard Worker     UniqueDBusMessage NewSignalMessage(const std::string &aInterfaceName, const std::string &aSignalName);
237*4a64e381SAndroid Build Coastguard Worker 
238*4a64e381SAndroid Build Coastguard Worker     std::unordered_map<std::string, MethodHandlerType>                                    mMethodHandlers;
239*4a64e381SAndroid Build Coastguard Worker     std::unordered_map<std::string, std::unordered_map<std::string, PropertyHandlerType>> mGetPropertyHandlers;
240*4a64e381SAndroid Build Coastguard Worker     std::unordered_map<std::string, std::unordered_map<std::string, AsyncPropertyHandlerType>>
241*4a64e381SAndroid Build Coastguard Worker                                                          mAsyncGetPropertyHandlers;
242*4a64e381SAndroid Build Coastguard Worker     std::unordered_map<std::string, PropertyHandlerType> mSetPropertyHandlers;
243*4a64e381SAndroid Build Coastguard Worker     DBusConnection                                      *mConnection;
244*4a64e381SAndroid Build Coastguard Worker     std::string                                          mObjectPath;
245*4a64e381SAndroid Build Coastguard Worker };
246*4a64e381SAndroid Build Coastguard Worker 
247*4a64e381SAndroid Build Coastguard Worker } // namespace DBus
248*4a64e381SAndroid Build Coastguard Worker } // namespace otbr
249*4a64e381SAndroid Build Coastguard Worker 
250*4a64e381SAndroid Build Coastguard Worker #endif // OTBR_DBUS_DBUS_SERVER_HPP_
251