1c95cf671SFeist, James /* 2c95cf671SFeist, James // Copyright (c) 2019 Intel Corporation 3c95cf671SFeist, James // 4c95cf671SFeist, James // Licensed under the Apache License, Version 2.0 (the "License"); 5c95cf671SFeist, James // you may not use this file except in compliance with the License. 6c95cf671SFeist, James // You may obtain a copy of the License at 7c95cf671SFeist, James // 8c95cf671SFeist, James // http://www.apache.org/licenses/LICENSE-2.0 9c95cf671SFeist, James // 10c95cf671SFeist, James // Unless required by applicable law or agreed to in writing, software 11c95cf671SFeist, James // distributed under the License is distributed on an "AS IS" BASIS, 12c95cf671SFeist, James // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c95cf671SFeist, James // See the License for the specific language governing permissions and 14c95cf671SFeist, James // limitations under the License. 15c95cf671SFeist, James */ 16c95cf671SFeist, James 17*e881852bSJames Feist #include <systemd/sd-journal.h> 18*e881852bSJames Feist 199f6565dbSJames Feist #include <boost/algorithm/string/predicate.hpp> 209f6565dbSJames Feist #include <boost/asio/io_context.hpp> 219f6565dbSJames Feist #include <boost/asio/steady_timer.hpp> 229f6565dbSJames Feist #include <boost/container/flat_map.hpp> 23c95cf671SFeist, James #include <cstdint> 249f6565dbSJames Feist #include <iostream> 259f6565dbSJames Feist #include <sdbusplus/asio/connection.hpp> 26c95cf671SFeist, James #include <string> 27c95cf671SFeist, James #include <variant> 28c95cf671SFeist, James #include <vector> 29c95cf671SFeist, James 30c95cf671SFeist, James using GetSubTreeType = std::vector< 31c95cf671SFeist, James std::pair<std::string, 32c95cf671SFeist, James std::vector<std::pair<std::string, std::vector<std::string>>>>>; 33c95cf671SFeist, James using BasicVariantType = 34c95cf671SFeist, James std::variant<std::vector<std::string>, std::string, int64_t, uint64_t, 35c95cf671SFeist, James double, int32_t, uint32_t, int16_t, uint16_t, uint8_t, bool>; 360b236ab8SJames Feist using Association = std::tuple<std::string, std::string, std::string>; 37c95cf671SFeist, James 38c95cf671SFeist, James namespace mapper 39c95cf671SFeist, James { 40c95cf671SFeist, James constexpr const char* busName = "xyz.openbmc_project.ObjectMapper"; 41c95cf671SFeist, James constexpr const char* path = "/xyz/openbmc_project/object_mapper"; 42c95cf671SFeist, James constexpr const char* interface = "xyz.openbmc_project.ObjectMapper"; 43c95cf671SFeist, James constexpr const char* subtree = "GetSubTree"; 44c95cf671SFeist, James } // namespace mapper 45c95cf671SFeist, James 46c95cf671SFeist, James namespace entityManager 47c95cf671SFeist, James { 48c95cf671SFeist, James constexpr const char* busName = "xyz.openbmc_project.EntityManager"; 49c95cf671SFeist, James } // namespace entityManager 50c95cf671SFeist, James 51c95cf671SFeist, James namespace inventory 52c95cf671SFeist, James { 53c95cf671SFeist, James constexpr const char* interface = "xyz.openbmc_project.Inventory.Item"; 54c95cf671SFeist, James } // namespace inventory 55c95cf671SFeist, James 5609dd2314SJames Feist namespace ledGroup 5709dd2314SJames Feist { 5809dd2314SJames Feist constexpr const char* interface = "xyz.openbmc_project.Led.Group"; 5909dd2314SJames Feist constexpr const char* asserted = "Asserted"; 6009dd2314SJames Feist } // namespace ledGroup 6109dd2314SJames Feist 629f6565dbSJames Feist namespace properties 639f6565dbSJames Feist { 649f6565dbSJames Feist constexpr const char* interface = "org.freedesktop.DBus.Properties"; 659f6565dbSJames Feist constexpr const char* get = "Get"; 669f6565dbSJames Feist } // namespace properties 679f6565dbSJames Feist 689f6565dbSJames Feist namespace power 699f6565dbSJames Feist { 709f6565dbSJames Feist const static constexpr char* busname = "xyz.openbmc_project.State.Host"; 719f6565dbSJames Feist const static constexpr char* interface = "xyz.openbmc_project.State.Host"; 729f6565dbSJames Feist const static constexpr char* path = "/xyz/openbmc_project/state/host0"; 739f6565dbSJames Feist const static constexpr char* property = "CurrentHostState"; 749f6565dbSJames Feist } // namespace power 759f6565dbSJames Feist 7642b49c17SJames Feist namespace association 7742b49c17SJames Feist { 7842b49c17SJames Feist const static constexpr char* interface = 7942b49c17SJames Feist "xyz.openbmc_project.Association.Definitions"; 8042b49c17SJames Feist } // namespace association 8142b49c17SJames Feist 82c95cf671SFeist, James namespace hsbp 83c95cf671SFeist, James { 84c95cf671SFeist, James enum class registers : uint8_t 85c95cf671SFeist, James { 86c95cf671SFeist, James fpgaIdH = 0x0, 87c95cf671SFeist, James fpgaIdL = 0x1, 88c95cf671SFeist, James typeId = 0x2, 89c95cf671SFeist, James bootVer = 0x3, 90c95cf671SFeist, James fpgaVer = 0x4, 91c95cf671SFeist, James securityRev = 0x5, 92c95cf671SFeist, James funSupported = 0x6, 93c95cf671SFeist, James numDisks = 0x7, 94c95cf671SFeist, James presence = 0x8, 95c95cf671SFeist, James ssdIFDET = 0x9, 96c95cf671SFeist, James ifdetPart = 0xA, 97c95cf671SFeist, James statusLocate = 0xB, 98c95cf671SFeist, James statusFail = 0xC, 99c95cf671SFeist, James statusRebuild = 0xD, 100c95cf671SFeist, James ledOverride = 0xE, 101c95cf671SFeist, James ledStatus = 0xF, 102c95cf671SFeist, James ledPattern0 = 0x10, 103c95cf671SFeist, James ledPattern1 = 0x11, 104c95cf671SFeist, James ledPattern2 = 0x12, 105c95cf671SFeist, James ledPattern3 = 0x13, 106c95cf671SFeist, James ledPattern4 = 0x14, 107c95cf671SFeist, James ledPattern5 = 0x15, 108c95cf671SFeist, James ledPattern6 = 0x16, 109c95cf671SFeist, James ledPattern7 = 0x17, 110c95cf671SFeist, James }; 111c95cf671SFeist, James 112c95cf671SFeist, James } // namespace hsbp 1139f6565dbSJames Feist 1149f6565dbSJames Feist static std::unique_ptr<sdbusplus::bus::match::match> powerMatch = nullptr; 1159f6565dbSJames Feist static bool powerStatusOn = false; 1169f6565dbSJames Feist 1179f6565dbSJames Feist bool isPowerOn(void) 1189f6565dbSJames Feist { 1199f6565dbSJames Feist if (!powerMatch) 1209f6565dbSJames Feist { 1219f6565dbSJames Feist throw std::runtime_error("Power Match Not Created"); 1229f6565dbSJames Feist } 1239f6565dbSJames Feist return powerStatusOn; 1249f6565dbSJames Feist } 1259f6565dbSJames Feist 1269f6565dbSJames Feist void setupPowerMatch(const std::shared_ptr<sdbusplus::asio::connection>& conn) 1279f6565dbSJames Feist { 1289f6565dbSJames Feist static boost::asio::steady_timer timer(conn->get_io_context()); 1299f6565dbSJames Feist // create a match for powergood changes, first time do a method call to 1309f6565dbSJames Feist // cache the correct value 1319f6565dbSJames Feist if (powerMatch) 1329f6565dbSJames Feist { 1339f6565dbSJames Feist return; 1349f6565dbSJames Feist } 1359f6565dbSJames Feist 1369f6565dbSJames Feist powerMatch = std::make_unique<sdbusplus::bus::match::match>( 1379f6565dbSJames Feist static_cast<sdbusplus::bus::bus&>(*conn), 1389f6565dbSJames Feist "type='signal',interface='" + std::string(properties::interface) + 1399f6565dbSJames Feist "',path='" + std::string(power::path) + "',arg0='" + 1409f6565dbSJames Feist std::string(power::interface) + "'", 1419f6565dbSJames Feist [](sdbusplus::message::message& message) { 1429f6565dbSJames Feist std::string objectName; 1439f6565dbSJames Feist boost::container::flat_map<std::string, std::variant<std::string>> 1449f6565dbSJames Feist values; 1459f6565dbSJames Feist message.read(objectName, values); 1469f6565dbSJames Feist auto findState = values.find(power::property); 1479f6565dbSJames Feist if (findState != values.end()) 1489f6565dbSJames Feist { 1499f6565dbSJames Feist bool on = boost::ends_with( 1509f6565dbSJames Feist std::get<std::string>(findState->second), "Running"); 1519f6565dbSJames Feist if (!on) 1529f6565dbSJames Feist { 1539f6565dbSJames Feist timer.cancel(); 1549f6565dbSJames Feist powerStatusOn = false; 1559f6565dbSJames Feist return; 1569f6565dbSJames Feist } 1579f6565dbSJames Feist // on comes too quickly 1589f6565dbSJames Feist timer.expires_after(std::chrono::seconds(10)); 1599f6565dbSJames Feist timer.async_wait([](boost::system::error_code ec) { 1609f6565dbSJames Feist if (ec == boost::asio::error::operation_aborted) 1619f6565dbSJames Feist { 1629f6565dbSJames Feist return; 1639f6565dbSJames Feist } 1649f6565dbSJames Feist else if (ec) 1659f6565dbSJames Feist { 1669f6565dbSJames Feist std::cerr << "Timer error " << ec.message() << "\n"; 1679f6565dbSJames Feist return; 1689f6565dbSJames Feist } 1699f6565dbSJames Feist powerStatusOn = true; 1709f6565dbSJames Feist }); 1719f6565dbSJames Feist } 1729f6565dbSJames Feist }); 1739f6565dbSJames Feist 1749f6565dbSJames Feist conn->async_method_call( 1759f6565dbSJames Feist [](boost::system::error_code ec, 1769f6565dbSJames Feist const std::variant<std::string>& state) { 1779f6565dbSJames Feist if (ec) 1789f6565dbSJames Feist { 1799f6565dbSJames Feist // we commonly come up before power control, we'll capture the 1809f6565dbSJames Feist // property change later 1819f6565dbSJames Feist return; 1829f6565dbSJames Feist } 1839f6565dbSJames Feist powerStatusOn = 1849f6565dbSJames Feist boost::ends_with(std::get<std::string>(state), "Running"); 1859f6565dbSJames Feist }, 1869f6565dbSJames Feist power::busname, power::path, properties::interface, properties::get, 1879f6565dbSJames Feist power::interface, power::property); 1889f6565dbSJames Feist } 189*e881852bSJames Feist 190*e881852bSJames Feist inline void logDeviceAdded(const std::string& model, const std::string& type, 191*e881852bSJames Feist const std::string& sn) 192*e881852bSJames Feist { 193*e881852bSJames Feist sd_journal_send("MESSAGE=%s", "Inventory Added", "PRIORITY=%i", LOG_ERR, 194*e881852bSJames Feist "REDFISH_MESSAGE_ID=%s", "OpenBMC.0.1.InventoryAdded", 195*e881852bSJames Feist "REDFISH_MESSAGE_ARGS=%s,%s,%s", model.c_str(), 196*e881852bSJames Feist type.c_str(), sn.c_str(), NULL); 197*e881852bSJames Feist } 198*e881852bSJames Feist 199*e881852bSJames Feist inline void logDeviceRemoved(const std::string& model, const std::string& type, 200*e881852bSJames Feist const std::string& sn) 201*e881852bSJames Feist { 202*e881852bSJames Feist sd_journal_send("MESSAGE=%s", "Inventory Removed", "PRIORITY=%i", LOG_ERR, 203*e881852bSJames Feist "REDFISH_MESSAGE_ID=%s", "OpenBMC.0.1.InventoryRemoved", 204*e881852bSJames Feist "REDFISH_MESSAGE_ARGS=%s,%s,%s", model.c_str(), 205*e881852bSJames Feist type.c_str(), sn.c_str(), NULL); 206*e881852bSJames Feist } 207*e881852bSJames Feist 208*e881852bSJames Feist inline void logDriveError(const std::string& name) 209*e881852bSJames Feist { 210*e881852bSJames Feist sd_journal_send("MESSAGE=%s", "Drive Error", "PRIORITY=%i", LOG_ERR, 211*e881852bSJames Feist "REDFISH_MESSAGE_ID=%s", "OpenBMC.0.1.DriveError", 212*e881852bSJames Feist "REDFISH_MESSAGE_ARGS=%s", name.c_str(), NULL); 213*e881852bSJames Feist } 214