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