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