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