xref: /openbmc/entity-manager/src/utils.hpp (revision a5d25dcc)
1*a5d25dccSAndrew Jeffery /*
2*a5d25dccSAndrew Jeffery // Copyright (c) 2017 Intel Corporation
3*a5d25dccSAndrew Jeffery //
4*a5d25dccSAndrew Jeffery // Licensed under the Apache License, Version 2.0 (the "License");
5*a5d25dccSAndrew Jeffery // you may not use this file except in compliance with the License.
6*a5d25dccSAndrew Jeffery // You may obtain a copy of the License at
7*a5d25dccSAndrew Jeffery //
8*a5d25dccSAndrew Jeffery //      http://www.apache.org/licenses/LICENSE-2.0
9*a5d25dccSAndrew Jeffery //
10*a5d25dccSAndrew Jeffery // Unless required by applicable law or agreed to in writing, software
11*a5d25dccSAndrew Jeffery // distributed under the License is distributed on an "AS IS" BASIS,
12*a5d25dccSAndrew Jeffery // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*a5d25dccSAndrew Jeffery // See the License for the specific language governing permissions and
14*a5d25dccSAndrew Jeffery // limitations under the License.
15*a5d25dccSAndrew Jeffery */
16*a5d25dccSAndrew Jeffery /// \file utils.hpp
17*a5d25dccSAndrew Jeffery 
18*a5d25dccSAndrew Jeffery #pragma once
19*a5d25dccSAndrew Jeffery 
20*a5d25dccSAndrew Jeffery #include <boost/container/flat_map.hpp>
21*a5d25dccSAndrew Jeffery #include <nlohmann/json.hpp>
22*a5d25dccSAndrew Jeffery #include <sdbusplus/asio/connection.hpp>
23*a5d25dccSAndrew Jeffery #include <sdbusplus/exception.hpp>
24*a5d25dccSAndrew Jeffery 
25*a5d25dccSAndrew Jeffery #include <filesystem>
26*a5d25dccSAndrew Jeffery #include <fstream>
27*a5d25dccSAndrew Jeffery #include <iostream>
28*a5d25dccSAndrew Jeffery 
29*a5d25dccSAndrew Jeffery constexpr const char* configurationOutDir = "/var/configuration/";
30*a5d25dccSAndrew Jeffery constexpr const char* versionHashFile = "/var/configuration/version";
31*a5d25dccSAndrew Jeffery constexpr const char* versionFile = "/etc/os-release";
32*a5d25dccSAndrew Jeffery 
33*a5d25dccSAndrew Jeffery extern boost::asio::io_context io;
34*a5d25dccSAndrew Jeffery 
35*a5d25dccSAndrew Jeffery using DBusValueVariant =
36*a5d25dccSAndrew Jeffery     std::variant<std::string, int64_t, uint64_t, double, int32_t, uint32_t,
37*a5d25dccSAndrew Jeffery                  int16_t, uint16_t, uint8_t, bool, std::vector<uint8_t>>;
38*a5d25dccSAndrew Jeffery using DBusInterface = boost::container::flat_map<std::string, DBusValueVariant>;
39*a5d25dccSAndrew Jeffery using DBusObject = boost::container::flat_map<std::string, DBusInterface>;
40*a5d25dccSAndrew Jeffery using MapperGetSubTreeResponse =
41*a5d25dccSAndrew Jeffery     boost::container::flat_map<std::string, DBusObject>;
42*a5d25dccSAndrew Jeffery 
43*a5d25dccSAndrew Jeffery namespace properties
44*a5d25dccSAndrew Jeffery {
45*a5d25dccSAndrew Jeffery constexpr const char* interface = "org.freedesktop.DBus.Properties";
46*a5d25dccSAndrew Jeffery constexpr const char* get = "Get";
47*a5d25dccSAndrew Jeffery } // namespace properties
48*a5d25dccSAndrew Jeffery 
49*a5d25dccSAndrew Jeffery namespace power
50*a5d25dccSAndrew Jeffery {
51*a5d25dccSAndrew Jeffery const static constexpr char* busname = "xyz.openbmc_project.State.Host";
52*a5d25dccSAndrew Jeffery const static constexpr char* interface = "xyz.openbmc_project.State.Host";
53*a5d25dccSAndrew Jeffery const static constexpr char* path = "/xyz/openbmc_project/state/host0";
54*a5d25dccSAndrew Jeffery const static constexpr char* property = "CurrentHostState";
55*a5d25dccSAndrew Jeffery } // namespace power
56*a5d25dccSAndrew Jeffery 
57*a5d25dccSAndrew Jeffery bool findFiles(const std::filesystem::path& dirPath,
58*a5d25dccSAndrew Jeffery                const std::string& matchString,
59*a5d25dccSAndrew Jeffery                std::vector<std::filesystem::path>& foundPaths);
60*a5d25dccSAndrew Jeffery bool findFiles(const std::vector<std::filesystem::path>&& dirPaths,
61*a5d25dccSAndrew Jeffery                const std::string& matchString,
62*a5d25dccSAndrew Jeffery                std::vector<std::filesystem::path>& foundPaths);
63*a5d25dccSAndrew Jeffery 
64*a5d25dccSAndrew Jeffery bool getI2cDevicePaths(
65*a5d25dccSAndrew Jeffery     const std::filesystem::path& dirPath,
66*a5d25dccSAndrew Jeffery     boost::container::flat_map<size_t, std::filesystem::path>& busPaths);
67*a5d25dccSAndrew Jeffery 
68*a5d25dccSAndrew Jeffery bool validateJson(const nlohmann::json& schemaFile,
69*a5d25dccSAndrew Jeffery                   const nlohmann::json& input);
70*a5d25dccSAndrew Jeffery 
71*a5d25dccSAndrew Jeffery bool isPowerOn(void);
72*a5d25dccSAndrew Jeffery void setupPowerMatch(const std::shared_ptr<sdbusplus::asio::connection>& conn);
73*a5d25dccSAndrew Jeffery struct DBusInternalError final : public sdbusplus::exception_t
74*a5d25dccSAndrew Jeffery {
75*a5d25dccSAndrew Jeffery     const char* name() const noexcept override
76*a5d25dccSAndrew Jeffery     {
77*a5d25dccSAndrew Jeffery         return "org.freedesktop.DBus.Error.Failed";
78*a5d25dccSAndrew Jeffery     }
79*a5d25dccSAndrew Jeffery     const char* description() const noexcept override
80*a5d25dccSAndrew Jeffery     {
81*a5d25dccSAndrew Jeffery         return "internal error";
82*a5d25dccSAndrew Jeffery     }
83*a5d25dccSAndrew Jeffery     const char* what() const noexcept override
84*a5d25dccSAndrew Jeffery     {
85*a5d25dccSAndrew Jeffery         return "org.freedesktop.DBus.Error.Failed: "
86*a5d25dccSAndrew Jeffery                "internal error";
87*a5d25dccSAndrew Jeffery     }
88*a5d25dccSAndrew Jeffery 
89*a5d25dccSAndrew Jeffery     int get_errno() const noexcept override
90*a5d25dccSAndrew Jeffery     {
91*a5d25dccSAndrew Jeffery         return EACCES;
92*a5d25dccSAndrew Jeffery     }
93*a5d25dccSAndrew Jeffery };
94*a5d25dccSAndrew Jeffery 
95*a5d25dccSAndrew Jeffery inline bool fwVersionIsSame(void)
96*a5d25dccSAndrew Jeffery {
97*a5d25dccSAndrew Jeffery     std::ifstream version(versionFile);
98*a5d25dccSAndrew Jeffery     if (!version.good())
99*a5d25dccSAndrew Jeffery     {
100*a5d25dccSAndrew Jeffery         std::cerr << "Can't read " << versionFile << "\n";
101*a5d25dccSAndrew Jeffery         return false;
102*a5d25dccSAndrew Jeffery     }
103*a5d25dccSAndrew Jeffery 
104*a5d25dccSAndrew Jeffery     std::string versionData;
105*a5d25dccSAndrew Jeffery     std::string line;
106*a5d25dccSAndrew Jeffery     while (std::getline(version, line))
107*a5d25dccSAndrew Jeffery     {
108*a5d25dccSAndrew Jeffery         versionData += line;
109*a5d25dccSAndrew Jeffery     }
110*a5d25dccSAndrew Jeffery 
111*a5d25dccSAndrew Jeffery     std::string expectedHash =
112*a5d25dccSAndrew Jeffery         std::to_string(std::hash<std::string>{}(versionData));
113*a5d25dccSAndrew Jeffery 
114*a5d25dccSAndrew Jeffery     std::filesystem::create_directory(configurationOutDir);
115*a5d25dccSAndrew Jeffery     std::ifstream hashFile(versionHashFile);
116*a5d25dccSAndrew Jeffery     if (hashFile.good())
117*a5d25dccSAndrew Jeffery     {
118*a5d25dccSAndrew Jeffery 
119*a5d25dccSAndrew Jeffery         std::string hashString;
120*a5d25dccSAndrew Jeffery         hashFile >> hashString;
121*a5d25dccSAndrew Jeffery 
122*a5d25dccSAndrew Jeffery         if (expectedHash == hashString)
123*a5d25dccSAndrew Jeffery         {
124*a5d25dccSAndrew Jeffery             return true;
125*a5d25dccSAndrew Jeffery         }
126*a5d25dccSAndrew Jeffery         hashFile.close();
127*a5d25dccSAndrew Jeffery     }
128*a5d25dccSAndrew Jeffery 
129*a5d25dccSAndrew Jeffery     std::ofstream output(versionHashFile);
130*a5d25dccSAndrew Jeffery     output << expectedHash;
131*a5d25dccSAndrew Jeffery     return false;
132*a5d25dccSAndrew Jeffery }
133*a5d25dccSAndrew Jeffery 
134*a5d25dccSAndrew Jeffery std::optional<std::string> templateCharReplace(
135*a5d25dccSAndrew Jeffery     nlohmann::json::iterator& keyPair, const DBusObject& object, size_t index,
136*a5d25dccSAndrew Jeffery     const std::optional<std::string>& replaceStr = std::nullopt);
137*a5d25dccSAndrew Jeffery 
138*a5d25dccSAndrew Jeffery std::optional<std::string> templateCharReplace(
139*a5d25dccSAndrew Jeffery     nlohmann::json::iterator& keyPair, const DBusInterface& interface,
140*a5d25dccSAndrew Jeffery     size_t index, const std::optional<std::string>& replaceStr = std::nullopt);
141*a5d25dccSAndrew Jeffery 
142*a5d25dccSAndrew Jeffery inline bool deviceHasLogging(const nlohmann::json& json)
143*a5d25dccSAndrew Jeffery {
144*a5d25dccSAndrew Jeffery     auto logging = json.find("Logging");
145*a5d25dccSAndrew Jeffery     if (logging != json.end())
146*a5d25dccSAndrew Jeffery     {
147*a5d25dccSAndrew Jeffery         const auto* ptr = logging->get_ptr<const std::string*>();
148*a5d25dccSAndrew Jeffery         if (ptr != nullptr)
149*a5d25dccSAndrew Jeffery         {
150*a5d25dccSAndrew Jeffery             if (*ptr == "Off")
151*a5d25dccSAndrew Jeffery             {
152*a5d25dccSAndrew Jeffery                 return false;
153*a5d25dccSAndrew Jeffery             }
154*a5d25dccSAndrew Jeffery         }
155*a5d25dccSAndrew Jeffery     }
156*a5d25dccSAndrew Jeffery     return true;
157*a5d25dccSAndrew Jeffery }
158*a5d25dccSAndrew Jeffery 
159*a5d25dccSAndrew Jeffery /// \brief Match a Dbus property against a probe statement.
160*a5d25dccSAndrew Jeffery /// \param probe the probe statement to match against.
161*a5d25dccSAndrew Jeffery /// \param dbusValue the property value being matched to a probe.
162*a5d25dccSAndrew Jeffery /// \return true if the dbusValue matched the probe otherwise false.
163*a5d25dccSAndrew Jeffery bool matchProbe(const nlohmann::json& probe, const DBusValueVariant& dbusValue);
164