• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 request.
32  */
33 
34 #ifndef OTBR_LOG_TAG
35 #define OTBR_LOG_TAG "DBUS"
36 #endif
37 
38 #include "common/code_utils.hpp"
39 #include "common/logging.hpp"
40 
41 #include "dbus/common/dbus_message_dump.hpp"
42 #include "dbus/common/dbus_message_helper.hpp"
43 #include "dbus/common/dbus_resources.hpp"
44 #include "dbus/server/error_helper.hpp"
45 
46 namespace otbr {
47 namespace DBus {
48 
49 /**
50  * This class represents a incoming call for a d-bus method.
51  *
52  */
53 class DBusRequest
54 {
55 public:
56     /**
57      * The constructor of dbus request.
58      *
59      * @param[in] aConnection  The dbus connection.
60      * @param[in] aMessage     The incoming dbus message.
61      *
62      */
DBusRequest(DBusConnection * aConnection,DBusMessage * aMessage)63     DBusRequest(DBusConnection *aConnection, DBusMessage *aMessage)
64         : mConnection(aConnection)
65         , mMessage(aMessage)
66     {
67         dbus_message_ref(aMessage);
68         dbus_connection_ref(aConnection);
69     }
70 
71     /**
72      * The copy constructor of dbus request.
73      *
74      * @param[in] aOther  The object to be copied from.
75      *
76      */
DBusRequest(const DBusRequest & aOther)77     DBusRequest(const DBusRequest &aOther)
78         : mConnection(nullptr)
79         , mMessage(nullptr)
80     {
81         CopyFrom(aOther);
82     }
83 
84     /**
85      * The assignment operator of dbus request.
86      *
87      * @param[in] aOther  The object to be copied from.
88      *
89      */
operator =(const DBusRequest & aOther)90     DBusRequest &operator=(const DBusRequest &aOther)
91     {
92         CopyFrom(aOther);
93         return *this;
94     }
95 
96     /**
97      * This method returns the message sent to call the d-bus method.
98      *
99      * @returns The dbus message.
100      *
101      */
GetMessage(void)102     DBusMessage *GetMessage(void) { return mMessage; }
103 
104     /**
105      * This method returns underlying d-bus connection.
106      *
107      * @returns The dbus connection.
108      *
109      */
GetConnection(void)110     DBusConnection *GetConnection(void) { return mConnection; }
111 
112     /**
113      * This method replies to the d-bus method call.
114      *
115      * @param[in] aReply  The tuple to be sent.
116      *
117      */
Reply(const std::tuple<Args...> & aReply)118     template <typename... Args> void Reply(const std::tuple<Args...> &aReply)
119     {
120         UniqueDBusMessage reply{dbus_message_new_method_return(mMessage)};
121 
122         VerifyOrExit(reply != nullptr);
123         VerifyOrExit(otbr::DBus::TupleToDBusMessage(*reply, aReply) == OTBR_ERROR_NONE);
124 
125         if (otbrLogGetLevel() >= OTBR_LOG_DEBUG)
126         {
127             otbrLogDebug("Replied to %s.%s :", dbus_message_get_interface(mMessage), dbus_message_get_member(mMessage));
128             DumpDBusMessage(*reply);
129         }
130         dbus_connection_send(mConnection, reply.get(), nullptr);
131 
132     exit:
133         return;
134     }
135 
136     /**
137      * This method replies an otError to the d-bus method call.
138      *
139      * @param[in] aError  The error to be sent.
140      * @param[in] aResult The return value of the method call, if any.
141      *
142      */
143     template <typename ResultType = int>
ReplyOtResult(otError aError,Optional<ResultType> aResult=Optional<ResultType> ())144     void ReplyOtResult(otError aError, Optional<ResultType> aResult = Optional<ResultType>())
145     {
146         UniqueDBusMessage reply{nullptr};
147 
148         if (aError == OT_ERROR_NONE)
149         {
150             otbrLogInfo("Replied to %s.%s with result %s", dbus_message_get_interface(mMessage),
151                         dbus_message_get_member(mMessage), ConvertToDBusErrorName(aError));
152         }
153         else
154         {
155             otbrLogErr("Replied to %s.%s with result %s", dbus_message_get_interface(mMessage),
156                        dbus_message_get_member(mMessage), ConvertToDBusErrorName(aError));
157         }
158 
159         if (aError == OT_ERROR_NONE)
160         {
161             reply = UniqueDBusMessage(dbus_message_new_method_return(mMessage));
162         }
163         else
164         {
165             reply = UniqueDBusMessage(dbus_message_new_error(mMessage, ConvertToDBusErrorName(aError), nullptr));
166         }
167         VerifyOrDie(reply != nullptr, "Failed to allocate message");
168 
169         if (aResult.HasValue())
170         {
171             DBusMessageIter replyIter;
172             otbrError       error;
173 
174             dbus_message_iter_init_append(reply.get(), &replyIter);
175             error = DBusMessageEncode(&replyIter, *aResult);
176             VerifyOrDie(error == OTBR_ERROR_NONE, "Failed to encode result");
177         }
178 
179         dbus_connection_send(mConnection, reply.get(), nullptr);
180     }
181 
182     /**
183      * The destructor of DBusRequest
184      *
185      */
~DBusRequest(void)186     ~DBusRequest(void)
187     {
188         if (mConnection)
189         {
190             dbus_connection_unref(mConnection);
191         }
192         if (mMessage)
193         {
194             dbus_message_unref(mMessage);
195         }
196     }
197 
198 private:
CopyFrom(const DBusRequest & aOther)199     void CopyFrom(const DBusRequest &aOther)
200     {
201         if (mMessage)
202         {
203             dbus_message_unref(mMessage);
204         }
205         if (mConnection)
206         {
207             dbus_connection_unref(mConnection);
208         }
209         mConnection = aOther.mConnection;
210         mMessage    = aOther.mMessage;
211         dbus_message_ref(mMessage);
212         dbus_connection_ref(mConnection);
213     }
214 
215     DBusConnection *mConnection;
216     DBusMessage *   mMessage;
217 };
218 
219 } // namespace DBus
220 } // namespace otbr
221