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