xref: /openbmc/bmcweb/include/dbus_utility.hpp (revision e99073f5)
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