1 /* 2 // Copyright (c) 2018 Intel Corporation 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 */ 16 #pragma once 17 18 #include "dbus_singleton.hpp" 19 20 #include <boost/system/error_code.hpp> // IWYU pragma: keep 21 #include <sdbusplus/message/native_types.hpp> 22 23 #include <array> 24 #include <cstddef> 25 #include <cstdint> 26 #include <filesystem> 27 #include <functional> 28 #include <regex> 29 #include <span> 30 #include <sstream> 31 #include <string> 32 #include <string_view> 33 #include <tuple> 34 #include <utility> 35 #include <variant> 36 #include <vector> 37 38 // IWYU pragma: no_include <stddef.h> 39 // IWYU pragma: no_include <stdint.h> 40 // IWYU pragma: no_include <boost/system/detail/error_code.hpp> 41 42 namespace dbus 43 { 44 45 namespace utility 46 { 47 48 // clang-format off 49 using DbusVariantType = std::variant< 50 std::vector<std::tuple<std::string, std::string, std::string>>, 51 std::vector<std::string>, 52 std::vector<double>, 53 std::string, 54 int64_t, 55 uint64_t, 56 double, 57 int32_t, 58 uint32_t, 59 int16_t, 60 uint16_t, 61 uint8_t, 62 bool, 63 sdbusplus::message::unix_fd, 64 std::vector<uint32_t>, 65 std::vector<uint16_t>, 66 sdbusplus::message::object_path, 67 std::tuple<uint64_t, std::vector<std::tuple<std::string, std::string, double, uint64_t>>>, 68 std::vector<std::tuple<std::string, std::string>>, 69 std::vector<std::tuple<uint32_t, std::vector<uint32_t>>>, 70 std::vector<std::tuple<uint32_t, size_t>>, 71 std::vector<std::tuple<sdbusplus::message::object_path, std::string, 72 std::string, std::string>> 73 >; 74 75 // clang-format on 76 using DBusPropertiesMap = std::vector<std::pair<std::string, DbusVariantType>>; 77 using DBusInteracesMap = std::vector<std::pair<std::string, DBusPropertiesMap>>; 78 using ManagedObjectType = 79 std::vector<std::pair<sdbusplus::message::object_path, DBusInteracesMap>>; 80 81 // Map of service name to list of interfaces 82 using MapperServiceMap = 83 std::vector<std::pair<std::string, std::vector<std::string>>>; 84 85 // Map of object paths to MapperServiceMaps 86 using MapperGetSubTreeResponse = 87 std::vector<std::pair<std::string, MapperServiceMap>>; 88 89 using MapperGetObject = 90 std::vector<std::pair<std::string, std::vector<std::string>>>; 91 92 using MapperGetAncestorsResponse = std::vector< 93 std::pair<std::string, 94 std::vector<std::pair<std::string, std::vector<std::string>>>>>; 95 96 using MapperGetSubTreePathsResponse = std::vector<std::string>; 97 98 inline void escapePathForDbus(std::string& path) 99 { 100 const std::regex reg("[^A-Za-z0-9_/]"); 101 std::regex_replace(path.begin(), path.begin(), path.end(), reg, "_"); 102 } 103 104 // gets the string N strings deep into a path 105 // i.e. /0th/1st/2nd/3rd 106 inline bool getNthStringFromPath(const std::string& path, int index, 107 std::string& result) 108 { 109 if (index < 0) 110 { 111 return false; 112 } 113 114 std::filesystem::path p1(path); 115 int count = -1; 116 for (auto const& element : p1) 117 { 118 if (element.has_filename()) 119 { 120 ++count; 121 if (count == index) 122 { 123 result = element.stem().string(); 124 break; 125 } 126 } 127 } 128 return count >= index; 129 } 130 131 template <typename Callback> 132 inline void checkDbusPathExists(const std::string& path, Callback&& callback) 133 { 134 crow::connections::systemBus->async_method_call( 135 [callback{std::forward<Callback>(callback)}]( 136 const boost::system::error_code ec, 137 const dbus::utility::MapperGetObject& objectNames) { 138 callback(!ec && !objectNames.empty()); 139 }, 140 "xyz.openbmc_project.ObjectMapper", 141 "/xyz/openbmc_project/object_mapper", 142 "xyz.openbmc_project.ObjectMapper", "GetObject", path, 143 std::array<std::string, 0>()); 144 } 145 146 inline void 147 getSubTree(const std::string& path, int32_t depth, 148 std::span<const std::string_view> interfaces, 149 std::function<void(const boost::system::error_code&, 150 const MapperGetSubTreeResponse&)>&& callback) 151 { 152 crow::connections::systemBus->async_method_call( 153 [callback{std::move(callback)}]( 154 const boost::system::error_code ec, 155 const MapperGetSubTreeResponse& subtree) { callback(ec, subtree); }, 156 "xyz.openbmc_project.ObjectMapper", 157 "/xyz/openbmc_project/object_mapper", 158 "xyz.openbmc_project.ObjectMapper", "GetSubTree", path, depth, 159 interfaces); 160 } 161 162 inline void getSubTreePaths( 163 const std::string& path, int32_t depth, 164 std::span<const std::string_view> interfaces, 165 std::function<void(const boost::system::error_code&, 166 const MapperGetSubTreePathsResponse&)>&& callback) 167 { 168 crow::connections::systemBus->async_method_call( 169 [callback{std::move(callback)}]( 170 const boost::system::error_code ec, 171 const MapperGetSubTreePathsResponse& subtreePaths) { 172 callback(ec, subtreePaths); 173 }, 174 "xyz.openbmc_project.ObjectMapper", 175 "/xyz/openbmc_project/object_mapper", 176 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", path, depth, 177 interfaces); 178 } 179 180 inline void 181 getDbusObject(const std::string& path, 182 std::span<const std::string_view> interfaces, 183 std::function<void(const boost::system::error_code&, 184 const MapperGetObject&)>&& callback) 185 { 186 crow::connections::systemBus->async_method_call( 187 [callback{std::move(callback)}](const boost::system::error_code& ec, 188 const MapperGetObject& object) { 189 callback(ec, object); 190 }, 191 "xyz.openbmc_project.ObjectMapper", 192 "/xyz/openbmc_project/object_mapper", 193 "xyz.openbmc_project.ObjectMapper", "GetObject", path, interfaces); 194 } 195 196 } // namespace utility 197 } // namespace dbus 198