1 #include "config.h" 2 3 #include <sdbusplus/server.hpp> 4 5 #include <fstream> 6 #include <map> 7 #include <string> 8 9 namespace utils 10 { 11 12 using PropertyValue = std::variant<std::string>; 13 14 /** 15 * @brief Get the bus service 16 * 17 * @return the bus service as a string 18 **/ 19 std::string getService(sdbusplus::bus_t& bus, const std::string& path, 20 const std::string& interface); 21 22 /** @brief Get property(type: variant) 23 * 24 * @param[in] bus - bus handler 25 * @param[in] objectPath - D-Bus object path 26 * @param[in] interface - D-Bus interface 27 * @param[in] propertyName - D-Bus property name 28 * 29 * @return The value of the property(type: variant) 30 * 31 * @throw sdbusplus::exception_t when it fails 32 */ 33 template <typename T> 34 T getProperty(sdbusplus::bus_t& bus, const std::string& objectPath, 35 const std::string& interface, const std::string& propertyName) 36 { 37 std::variant<T> value{}; 38 auto service = getService(bus, objectPath, interface); 39 if (service.empty()) 40 { 41 return std::get<T>(value); 42 } 43 44 auto method = bus.new_method_call(service.c_str(), objectPath.c_str(), 45 "org.freedesktop.DBus.Properties", "Get"); 46 method.append(interface, propertyName); 47 48 auto reply = bus.call(method); 49 reply.read(value); 50 51 return std::get<T>(value); 52 } 53 54 /** @brief Set D-Bus property 55 * 56 * @param[in] bus - bus handler 57 * @param[in] objectPath - D-Bus object path 58 * @param[in] interface - D-Bus interface 59 * @param[in] propertyName - D-Bus property name 60 * @param[in] value - The value to be set 61 * 62 * @throw sdbusplus::exception_t when it fails 63 */ 64 void setProperty(sdbusplus::bus_t& bus, const std::string& objectPath, 65 const std::string& interface, const std::string& propertyName, 66 const PropertyValue& value); 67 68 /** 69 * @brief Merge more files 70 * 71 * @param[in] srcFiles - source files 72 * @param[out] dstFile - destination file 73 * @return 74 **/ 75 void mergeFiles(const std::vector<std::string>& srcFiles, 76 const std::string& dstFile); 77 78 namespace internal 79 { 80 81 /** 82 * @brief Construct an argument vector to be used with an exec command, which 83 * requires the name of the executable to be the first argument, and a 84 * null terminator to be the last. 85 * @param[in] name - Name of the executable 86 * @param[in] args - Optional arguments 87 * @return char* vector 88 */ 89 template <typename... Arg> 90 constexpr auto constructArgv(const char* name, Arg&&... args) 91 { 92 std::vector<char*> argV{ 93 {const_cast<char*>(name), const_cast<char*>(args)..., nullptr}}; 94 return argV; 95 } 96 97 /** 98 * @brief Helper function to execute command in child process 99 * @param[in] args - Executable plus optional arguments 100 * @return 0 and command output on success 101 */ 102 std::pair<int, std::string> executeCmd(char** args); 103 104 } // namespace internal 105 106 /** 107 * @brief Execute command in child process 108 * @param[in] path - Fully qualified name of the executable to run 109 * @param[in] args - Optional arguments 110 * @return 0 and command output on success 111 */ 112 template <typename... Arg> 113 std::pair<int, std::string> execute(const char* path, Arg&&... args) 114 { 115 auto argArray = internal::constructArgv(path, std::forward<Arg>(args)...); 116 117 return internal::executeCmd(argArray.data()); 118 } 119 120 } // namespace utils 121