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