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 { 76 const char* name() const noexcept override 77 { 78 return "org.freedesktop.DBus.Error.Failed"; 79 } 80 const char* description() const noexcept override 81 { 82 return "internal error"; 83 } 84 const char* what() const noexcept override 85 { 86 return "org.freedesktop.DBus.Error.Failed: " 87 "internal error"; 88 } 89 90 int get_errno() const noexcept override 91 { 92 return EACCES; 93 } 94 }; 95 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 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