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