xref: /openbmc/entity-manager/src/utils.hpp (revision fc171428)
1 /*
2 // Copyright (c) 2017 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 /// \file utils.hpp
17 
18 #pragma once
19 
20 #include <boost/container/flat_map.hpp>
21 #include <nlohmann/json.hpp>
22 #include <sdbusplus/asio/connection.hpp>
23 #include <sdbusplus/exception.hpp>
24 
25 #include <filesystem>
26 #include <fstream>
27 #include <iostream>
28 
29 constexpr const char* configurationOutDir = "/var/configuration/";
30 constexpr const char* versionHashFile = "/var/configuration/version";
31 constexpr const char* versionFile = "/etc/os-release";
32 
33 // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
34 extern boost::asio::io_context io;
35 
36 using DBusValueVariant =
37     std::variant<std::string, int64_t, uint64_t, double, int32_t, uint32_t,
38                  int16_t, uint16_t, uint8_t, bool, std::vector<uint8_t>>;
39 using DBusInterface = boost::container::flat_map<std::string, DBusValueVariant>;
40 using DBusObject = boost::container::flat_map<std::string, DBusInterface>;
41 using MapperGetSubTreeResponse =
42     boost::container::flat_map<std::string, DBusObject>;
43 
44 namespace properties
45 {
46 constexpr const char* interface = "org.freedesktop.DBus.Properties";
47 constexpr const char* get = "Get";
48 } // namespace properties
49 
50 namespace power
51 {
52 const static constexpr char* busname = "xyz.openbmc_project.State.Host";
53 const static constexpr char* interface = "xyz.openbmc_project.State.Host";
54 const static constexpr char* path = "/xyz/openbmc_project/state/host0";
55 const static constexpr char* property = "CurrentHostState";
56 } // namespace power
57 
58 bool findFiles(const std::filesystem::path& dirPath,
59                const std::string& matchString,
60                std::vector<std::filesystem::path>& foundPaths);
61 bool findFiles(const std::vector<std::filesystem::path>&& dirPaths,
62                const std::string& matchString,
63                std::vector<std::filesystem::path>& foundPaths);
64 
65 bool getI2cDevicePaths(
66     const std::filesystem::path& dirPath,
67     boost::container::flat_map<size_t, std::filesystem::path>& busPaths);
68 
69 bool validateJson(const nlohmann::json& schemaFile,
70                   const nlohmann::json& input);
71 
72 bool isPowerOn();
73 void setupPowerMatch(const std::shared_ptr<sdbusplus::asio::connection>& conn);
74 struct DBusInternalError final : public sdbusplus::exception_t
75 {
nameDBusInternalError76     const char* name() const noexcept override
77     {
78         return "org.freedesktop.DBus.Error.Failed";
79     }
descriptionDBusInternalError80     const char* description() const noexcept override
81     {
82         return "internal error";
83     }
whatDBusInternalError84     const char* what() const noexcept override
85     {
86         return "org.freedesktop.DBus.Error.Failed: "
87                "internal error";
88     }
89 
get_errnoDBusInternalError90     int get_errno() const noexcept override
91     {
92         return EACCES;
93     }
94 };
95 
fwVersionIsSame()96 inline bool fwVersionIsSame()
97 {
98     std::ifstream version(versionFile);
99     if (!version.good())
100     {
101         std::cerr << "Can't read " << versionFile << "\n";
102         return false;
103     }
104 
105     std::string versionData;
106     std::string line;
107     while (std::getline(version, line))
108     {
109         versionData += line;
110     }
111 
112     std::string expectedHash =
113         std::to_string(std::hash<std::string>{}(versionData));
114 
115     std::filesystem::create_directory(configurationOutDir);
116     std::ifstream hashFile(versionHashFile);
117     if (hashFile.good())
118     {
119         std::string hashString;
120         hashFile >> hashString;
121 
122         if (expectedHash == hashString)
123         {
124             return true;
125         }
126         hashFile.close();
127     }
128 
129     std::ofstream output(versionHashFile);
130     output << expectedHash;
131     return false;
132 }
133 
134 std::optional<std::string> templateCharReplace(
135     nlohmann::json::iterator& keyPair, const DBusObject& object, size_t index,
136     const std::optional<std::string>& replaceStr = std::nullopt);
137 
138 std::optional<std::string> templateCharReplace(
139     nlohmann::json::iterator& keyPair, const DBusInterface& interface,
140     size_t index, const std::optional<std::string>& replaceStr = std::nullopt);
141 
deviceHasLogging(const nlohmann::json & json)142 inline bool deviceHasLogging(const nlohmann::json& json)
143 {
144     auto logging = json.find("Logging");
145     if (logging != json.end())
146     {
147         const auto* ptr = logging->get_ptr<const std::string*>();
148         if (ptr != nullptr)
149         {
150             if (*ptr == "Off")
151             {
152                 return false;
153             }
154         }
155     }
156     return true;
157 }
158 
159 /// \brief Match a Dbus property against a probe statement.
160 /// \param probe the probe statement to match against.
161 /// \param dbusValue the property value being matched to a probe.
162 /// \return true if the dbusValue matched the probe otherwise false.
163 bool matchProbe(const nlohmann::json& probe, const DBusValueVariant& dbusValue);
164