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