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