xref: /openbmc/s2600wf-misc/hsbp-manager/include/utils.hpp (revision 9f6565db1fa663917cbac1f57e9507d6bf7565e6)
1 /*
2 // Copyright (c) 2019 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 
17 #include <boost/algorithm/string/predicate.hpp>
18 #include <boost/asio/io_context.hpp>
19 #include <boost/asio/steady_timer.hpp>
20 #include <boost/container/flat_map.hpp>
21 #include <cstdint>
22 #include <iostream>
23 #include <sdbusplus/asio/connection.hpp>
24 #include <string>
25 #include <variant>
26 #include <vector>
27 
28 using GetSubTreeType = std::vector<
29     std::pair<std::string,
30               std::vector<std::pair<std::string, std::vector<std::string>>>>>;
31 using BasicVariantType =
32     std::variant<std::vector<std::string>, std::string, int64_t, uint64_t,
33                  double, int32_t, uint32_t, int16_t, uint16_t, uint8_t, bool>;
34 using Association = std::tuple<std::string, std::string, std::string>;
35 
36 namespace mapper
37 {
38 constexpr const char* busName = "xyz.openbmc_project.ObjectMapper";
39 constexpr const char* path = "/xyz/openbmc_project/object_mapper";
40 constexpr const char* interface = "xyz.openbmc_project.ObjectMapper";
41 constexpr const char* subtree = "GetSubTree";
42 } // namespace mapper
43 
44 namespace entityManager
45 {
46 constexpr const char* busName = "xyz.openbmc_project.EntityManager";
47 } // namespace entityManager
48 
49 namespace inventory
50 {
51 constexpr const char* interface = "xyz.openbmc_project.Inventory.Item";
52 } // namespace inventory
53 
54 namespace ledGroup
55 {
56 constexpr const char* interface = "xyz.openbmc_project.Led.Group";
57 constexpr const char* asserted = "Asserted";
58 } // namespace ledGroup
59 
60 namespace properties
61 {
62 constexpr const char* interface = "org.freedesktop.DBus.Properties";
63 constexpr const char* get = "Get";
64 } // namespace properties
65 
66 namespace power
67 {
68 const static constexpr char* busname = "xyz.openbmc_project.State.Host";
69 const static constexpr char* interface = "xyz.openbmc_project.State.Host";
70 const static constexpr char* path = "/xyz/openbmc_project/state/host0";
71 const static constexpr char* property = "CurrentHostState";
72 } // namespace power
73 
74 namespace hsbp
75 {
76 enum class registers : uint8_t
77 {
78     fpgaIdH = 0x0,
79     fpgaIdL = 0x1,
80     typeId = 0x2,
81     bootVer = 0x3,
82     fpgaVer = 0x4,
83     securityRev = 0x5,
84     funSupported = 0x6,
85     numDisks = 0x7,
86     presence = 0x8,
87     ssdIFDET = 0x9,
88     ifdetPart = 0xA,
89     statusLocate = 0xB,
90     statusFail = 0xC,
91     statusRebuild = 0xD,
92     ledOverride = 0xE,
93     ledStatus = 0xF,
94     ledPattern0 = 0x10,
95     ledPattern1 = 0x11,
96     ledPattern2 = 0x12,
97     ledPattern3 = 0x13,
98     ledPattern4 = 0x14,
99     ledPattern5 = 0x15,
100     ledPattern6 = 0x16,
101     ledPattern7 = 0x17,
102 };
103 
104 } // namespace hsbp
105 
106 static std::unique_ptr<sdbusplus::bus::match::match> powerMatch = nullptr;
107 static bool powerStatusOn = false;
108 
109 bool isPowerOn(void)
110 {
111     if (!powerMatch)
112     {
113         throw std::runtime_error("Power Match Not Created");
114     }
115     return powerStatusOn;
116 }
117 
118 void setupPowerMatch(const std::shared_ptr<sdbusplus::asio::connection>& conn)
119 {
120     static boost::asio::steady_timer timer(conn->get_io_context());
121     // create a match for powergood changes, first time do a method call to
122     // cache the correct value
123     if (powerMatch)
124     {
125         return;
126     }
127 
128     powerMatch = std::make_unique<sdbusplus::bus::match::match>(
129         static_cast<sdbusplus::bus::bus&>(*conn),
130         "type='signal',interface='" + std::string(properties::interface) +
131             "',path='" + std::string(power::path) + "',arg0='" +
132             std::string(power::interface) + "'",
133         [](sdbusplus::message::message& message) {
134             std::string objectName;
135             boost::container::flat_map<std::string, std::variant<std::string>>
136                 values;
137             message.read(objectName, values);
138             auto findState = values.find(power::property);
139             if (findState != values.end())
140             {
141                 bool on = boost::ends_with(
142                     std::get<std::string>(findState->second), "Running");
143                 if (!on)
144                 {
145                     timer.cancel();
146                     powerStatusOn = false;
147                     return;
148                 }
149                 // on comes too quickly
150                 timer.expires_after(std::chrono::seconds(10));
151                 timer.async_wait([](boost::system::error_code ec) {
152                     if (ec == boost::asio::error::operation_aborted)
153                     {
154                         return;
155                     }
156                     else if (ec)
157                     {
158                         std::cerr << "Timer error " << ec.message() << "\n";
159                         return;
160                     }
161                     powerStatusOn = true;
162                 });
163             }
164         });
165 
166     conn->async_method_call(
167         [](boost::system::error_code ec,
168            const std::variant<std::string>& state) {
169             if (ec)
170             {
171                 // we commonly come up before power control, we'll capture the
172                 // property change later
173                 return;
174             }
175             powerStatusOn =
176                 boost::ends_with(std::get<std::string>(state), "Running");
177         },
178         power::busname, power::path, properties::interface, properties::get,
179         power::interface, power::property);
180 }
181