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