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