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 <tuple> 33 #include <utility> 34 #include <variant> 35 #include <vector> 36 37 // IWYU pragma: no_include <stddef.h> 38 // IWYU pragma: no_include <stdint.h> 39 // IWYU pragma: no_include <boost/system/detail/error_code.hpp> 40 41 namespace dbus 42 { 43 44 namespace utility 45 { 46 47 // clang-format off 48 using DbusVariantType = std::variant< 49 std::vector<std::tuple<std::string, std::string, std::string>>, 50 std::vector<std::string>, 51 std::vector<double>, 52 std::string, 53 int64_t, 54 uint64_t, 55 double, 56 int32_t, 57 uint32_t, 58 int16_t, 59 uint16_t, 60 uint8_t, 61 bool, 62 sdbusplus::message::unix_fd, 63 std::vector<uint32_t>, 64 std::vector<uint16_t>, 65 sdbusplus::message::object_path, 66 std::tuple<uint64_t, std::vector<std::tuple<std::string, std::string, double, uint64_t>>>, 67 std::vector<std::tuple<std::string, std::string>>, 68 std::vector<std::tuple<uint32_t, std::vector<uint32_t>>>, 69 std::vector<std::tuple<uint32_t, size_t>>, 70 std::vector<std::tuple<sdbusplus::message::object_path, std::string, 71 std::string, std::string>> 72 >; 73 74 // clang-format on 75 using DBusPropertiesMap = std::vector<std::pair<std::string, DbusVariantType>>; 76 using DBusInteracesMap = std::vector<std::pair<std::string, DBusPropertiesMap>>; 77 using ManagedObjectType = 78 std::vector<std::pair<sdbusplus::message::object_path, DBusInteracesMap>>; 79 80 // Map of service name to list of interfaces 81 using MapperServiceMap = 82 std::vector<std::pair<std::string, std::vector<std::string>>>; 83 84 // Map of object paths to MapperServiceMaps 85 using MapperGetSubTreeResponse = 86 std::vector<std::pair<std::string, MapperServiceMap>>; 87 88 using MapperGetObject = 89 std::vector<std::pair<std::string, std::vector<std::string>>>; 90 91 using MapperGetAncestorsResponse = std::vector< 92 std::pair<std::string, 93 std::vector<std::pair<std::string, std::vector<std::string>>>>>; 94 95 using MapperGetSubTreePathsResponse = std::vector<std::string>; 96 97 inline void escapePathForDbus(std::string& path) 98 { 99 const std::regex reg("[^A-Za-z0-9_/]"); 100 std::regex_replace(path.begin(), path.begin(), path.end(), reg, "_"); 101 } 102 103 // gets the string N strings deep into a path 104 // i.e. /0th/1st/2nd/3rd 105 inline bool getNthStringFromPath(const std::string& path, int index, 106 std::string& result) 107 { 108 if (index < 0) 109 { 110 return false; 111 } 112 113 std::filesystem::path p1(path); 114 int count = -1; 115 for (auto const& element : p1) 116 { 117 if (element.has_filename()) 118 { 119 ++count; 120 if (count == index) 121 { 122 result = element.stem().string(); 123 break; 124 } 125 } 126 } 127 return count >= index; 128 } 129 130 template <typename Callback> 131 inline void checkDbusPathExists(const std::string& path, Callback&& callback) 132 { 133 crow::connections::systemBus->async_method_call( 134 [callback{std::forward<Callback>(callback)}]( 135 const boost::system::error_code ec, 136 const dbus::utility::MapperGetObject& objectNames) { 137 callback(!ec && !objectNames.empty()); 138 }, 139 "xyz.openbmc_project.ObjectMapper", 140 "/xyz/openbmc_project/object_mapper", 141 "xyz.openbmc_project.ObjectMapper", "GetObject", path, 142 std::array<std::string, 0>()); 143 } 144 145 inline void 146 getSubTree(const std::string& path, std::span<std::string> interfaces, 147 std::function<void(const boost::system::error_code&, 148 const MapperGetSubTreeResponse&)>&& callback) 149 { 150 crow::connections::systemBus->async_method_call( 151 [callback{std::move(callback)}]( 152 const boost::system::error_code ec, 153 const MapperGetSubTreeResponse& subtree) { callback(ec, subtree); }, 154 "xyz.openbmc_project.ObjectMapper", 155 "/xyz/openbmc_project/object_mapper", 156 "xyz.openbmc_project.ObjectMapper", "GetSubTree", path, 0, interfaces); 157 } 158 159 inline void getSubTreePaths( 160 const std::string& path, std::span<std::string> interfaces, 161 std::function<void(const boost::system::error_code&, 162 const MapperGetSubTreePathsResponse&)>&& callback) 163 { 164 crow::connections::systemBus->async_method_call( 165 [callback{std::move(callback)}]( 166 const boost::system::error_code ec, 167 const MapperGetSubTreePathsResponse& subtreePaths) { 168 callback(ec, subtreePaths); 169 }, 170 "xyz.openbmc_project.ObjectMapper", 171 "/xyz/openbmc_project/object_mapper", 172 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", path, 0, 173 interfaces); 174 } 175 176 } // namespace utility 177 } // namespace dbus 178