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