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 179f6565dbSJames Feist #include <boost/algorithm/string/predicate.hpp> 189f6565dbSJames Feist #include <boost/asio/io_context.hpp> 199f6565dbSJames Feist #include <boost/asio/steady_timer.hpp> 209f6565dbSJames Feist #include <boost/container/flat_map.hpp> 21c95cf671SFeist, James #include <cstdint> 229f6565dbSJames Feist #include <iostream> 239f6565dbSJames Feist #include <sdbusplus/asio/connection.hpp> 24c95cf671SFeist, James #include <string> 25c95cf671SFeist, James #include <variant> 26c95cf671SFeist, James #include <vector> 27c95cf671SFeist, James 28c95cf671SFeist, James using GetSubTreeType = std::vector< 29c95cf671SFeist, James std::pair<std::string, 30c95cf671SFeist, James std::vector<std::pair<std::string, std::vector<std::string>>>>>; 31c95cf671SFeist, James using BasicVariantType = 32c95cf671SFeist, James std::variant<std::vector<std::string>, std::string, int64_t, uint64_t, 33c95cf671SFeist, James double, int32_t, uint32_t, int16_t, uint16_t, uint8_t, bool>; 340b236ab8SJames Feist using Association = std::tuple<std::string, std::string, std::string>; 35c95cf671SFeist, James 36c95cf671SFeist, James namespace mapper 37c95cf671SFeist, James { 38c95cf671SFeist, James constexpr const char* busName = "xyz.openbmc_project.ObjectMapper"; 39c95cf671SFeist, James constexpr const char* path = "/xyz/openbmc_project/object_mapper"; 40c95cf671SFeist, James constexpr const char* interface = "xyz.openbmc_project.ObjectMapper"; 41c95cf671SFeist, James constexpr const char* subtree = "GetSubTree"; 42c95cf671SFeist, James } // namespace mapper 43c95cf671SFeist, James 44c95cf671SFeist, James namespace entityManager 45c95cf671SFeist, James { 46c95cf671SFeist, James constexpr const char* busName = "xyz.openbmc_project.EntityManager"; 47c95cf671SFeist, James } // namespace entityManager 48c95cf671SFeist, James 49c95cf671SFeist, James namespace inventory 50c95cf671SFeist, James { 51c95cf671SFeist, James constexpr const char* interface = "xyz.openbmc_project.Inventory.Item"; 52c95cf671SFeist, James } // namespace inventory 53c95cf671SFeist, James 5409dd2314SJames Feist namespace ledGroup 5509dd2314SJames Feist { 5609dd2314SJames Feist constexpr const char* interface = "xyz.openbmc_project.Led.Group"; 5709dd2314SJames Feist constexpr const char* asserted = "Asserted"; 5809dd2314SJames Feist } // namespace ledGroup 5909dd2314SJames Feist 609f6565dbSJames Feist namespace properties 619f6565dbSJames Feist { 629f6565dbSJames Feist constexpr const char* interface = "org.freedesktop.DBus.Properties"; 639f6565dbSJames Feist constexpr const char* get = "Get"; 649f6565dbSJames Feist } // namespace properties 659f6565dbSJames Feist 669f6565dbSJames Feist namespace power 679f6565dbSJames Feist { 689f6565dbSJames Feist const static constexpr char* busname = "xyz.openbmc_project.State.Host"; 699f6565dbSJames Feist const static constexpr char* interface = "xyz.openbmc_project.State.Host"; 709f6565dbSJames Feist const static constexpr char* path = "/xyz/openbmc_project/state/host0"; 719f6565dbSJames Feist const static constexpr char* property = "CurrentHostState"; 729f6565dbSJames Feist } // namespace power 739f6565dbSJames Feist 74*42b49c17SJames Feist namespace association 75*42b49c17SJames Feist { 76*42b49c17SJames Feist const static constexpr char* interface = 77*42b49c17SJames Feist "xyz.openbmc_project.Association.Definitions"; 78*42b49c17SJames Feist } // namespace association 79*42b49c17SJames Feist 80c95cf671SFeist, James namespace hsbp 81c95cf671SFeist, James { 82c95cf671SFeist, James enum class registers : uint8_t 83c95cf671SFeist, James { 84c95cf671SFeist, James fpgaIdH = 0x0, 85c95cf671SFeist, James fpgaIdL = 0x1, 86c95cf671SFeist, James typeId = 0x2, 87c95cf671SFeist, James bootVer = 0x3, 88c95cf671SFeist, James fpgaVer = 0x4, 89c95cf671SFeist, James securityRev = 0x5, 90c95cf671SFeist, James funSupported = 0x6, 91c95cf671SFeist, James numDisks = 0x7, 92c95cf671SFeist, James presence = 0x8, 93c95cf671SFeist, James ssdIFDET = 0x9, 94c95cf671SFeist, James ifdetPart = 0xA, 95c95cf671SFeist, James statusLocate = 0xB, 96c95cf671SFeist, James statusFail = 0xC, 97c95cf671SFeist, James statusRebuild = 0xD, 98c95cf671SFeist, James ledOverride = 0xE, 99c95cf671SFeist, James ledStatus = 0xF, 100c95cf671SFeist, James ledPattern0 = 0x10, 101c95cf671SFeist, James ledPattern1 = 0x11, 102c95cf671SFeist, James ledPattern2 = 0x12, 103c95cf671SFeist, James ledPattern3 = 0x13, 104c95cf671SFeist, James ledPattern4 = 0x14, 105c95cf671SFeist, James ledPattern5 = 0x15, 106c95cf671SFeist, James ledPattern6 = 0x16, 107c95cf671SFeist, James ledPattern7 = 0x17, 108c95cf671SFeist, James }; 109c95cf671SFeist, James 110c95cf671SFeist, James } // namespace hsbp 1119f6565dbSJames Feist 1129f6565dbSJames Feist static std::unique_ptr<sdbusplus::bus::match::match> powerMatch = nullptr; 1139f6565dbSJames Feist static bool powerStatusOn = false; 1149f6565dbSJames Feist 1159f6565dbSJames Feist bool isPowerOn(void) 1169f6565dbSJames Feist { 1179f6565dbSJames Feist if (!powerMatch) 1189f6565dbSJames Feist { 1199f6565dbSJames Feist throw std::runtime_error("Power Match Not Created"); 1209f6565dbSJames Feist } 1219f6565dbSJames Feist return powerStatusOn; 1229f6565dbSJames Feist } 1239f6565dbSJames Feist 1249f6565dbSJames Feist void setupPowerMatch(const std::shared_ptr<sdbusplus::asio::connection>& conn) 1259f6565dbSJames Feist { 1269f6565dbSJames Feist static boost::asio::steady_timer timer(conn->get_io_context()); 1279f6565dbSJames Feist // create a match for powergood changes, first time do a method call to 1289f6565dbSJames Feist // cache the correct value 1299f6565dbSJames Feist if (powerMatch) 1309f6565dbSJames Feist { 1319f6565dbSJames Feist return; 1329f6565dbSJames Feist } 1339f6565dbSJames Feist 1349f6565dbSJames Feist powerMatch = std::make_unique<sdbusplus::bus::match::match>( 1359f6565dbSJames Feist static_cast<sdbusplus::bus::bus&>(*conn), 1369f6565dbSJames Feist "type='signal',interface='" + std::string(properties::interface) + 1379f6565dbSJames Feist "',path='" + std::string(power::path) + "',arg0='" + 1389f6565dbSJames Feist std::string(power::interface) + "'", 1399f6565dbSJames Feist [](sdbusplus::message::message& message) { 1409f6565dbSJames Feist std::string objectName; 1419f6565dbSJames Feist boost::container::flat_map<std::string, std::variant<std::string>> 1429f6565dbSJames Feist values; 1439f6565dbSJames Feist message.read(objectName, values); 1449f6565dbSJames Feist auto findState = values.find(power::property); 1459f6565dbSJames Feist if (findState != values.end()) 1469f6565dbSJames Feist { 1479f6565dbSJames Feist bool on = boost::ends_with( 1489f6565dbSJames Feist std::get<std::string>(findState->second), "Running"); 1499f6565dbSJames Feist if (!on) 1509f6565dbSJames Feist { 1519f6565dbSJames Feist timer.cancel(); 1529f6565dbSJames Feist powerStatusOn = false; 1539f6565dbSJames Feist return; 1549f6565dbSJames Feist } 1559f6565dbSJames Feist // on comes too quickly 1569f6565dbSJames Feist timer.expires_after(std::chrono::seconds(10)); 1579f6565dbSJames Feist timer.async_wait([](boost::system::error_code ec) { 1589f6565dbSJames Feist if (ec == boost::asio::error::operation_aborted) 1599f6565dbSJames Feist { 1609f6565dbSJames Feist return; 1619f6565dbSJames Feist } 1629f6565dbSJames Feist else if (ec) 1639f6565dbSJames Feist { 1649f6565dbSJames Feist std::cerr << "Timer error " << ec.message() << "\n"; 1659f6565dbSJames Feist return; 1669f6565dbSJames Feist } 1679f6565dbSJames Feist powerStatusOn = true; 1689f6565dbSJames Feist }); 1699f6565dbSJames Feist } 1709f6565dbSJames Feist }); 1719f6565dbSJames Feist 1729f6565dbSJames Feist conn->async_method_call( 1739f6565dbSJames Feist [](boost::system::error_code ec, 1749f6565dbSJames Feist const std::variant<std::string>& state) { 1759f6565dbSJames Feist if (ec) 1769f6565dbSJames Feist { 1779f6565dbSJames Feist // we commonly come up before power control, we'll capture the 1789f6565dbSJames Feist // property change later 1799f6565dbSJames Feist return; 1809f6565dbSJames Feist } 1819f6565dbSJames Feist powerStatusOn = 1829f6565dbSJames Feist boost::ends_with(std::get<std::string>(state), "Running"); 1839f6565dbSJames Feist }, 1849f6565dbSJames Feist power::busname, power::path, properties::interface, properties::get, 1859f6565dbSJames Feist power::interface, power::property); 1869f6565dbSJames Feist } 187