xref: /openbmc/s2600wf-misc/subprojects/hsbp-manager/include/utils.hpp (revision 69ae808e213f2e3ce5a0fc7e805820026065064c)
1*69ae808eSJason M. Bills /*
2*69ae808eSJason M. Bills // Copyright (c) 2019 Intel Corporation
3*69ae808eSJason M. Bills //
4*69ae808eSJason M. Bills // Licensed under the Apache License, Version 2.0 (the "License");
5*69ae808eSJason M. Bills // you may not use this file except in compliance with the License.
6*69ae808eSJason M. Bills // You may obtain a copy of the License at
7*69ae808eSJason M. Bills //
8*69ae808eSJason M. Bills //      http://www.apache.org/licenses/LICENSE-2.0
9*69ae808eSJason M. Bills //
10*69ae808eSJason M. Bills // Unless required by applicable law or agreed to in writing, software
11*69ae808eSJason M. Bills // distributed under the License is distributed on an "AS IS" BASIS,
12*69ae808eSJason M. Bills // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*69ae808eSJason M. Bills // See the License for the specific language governing permissions and
14*69ae808eSJason M. Bills // limitations under the License.
15*69ae808eSJason M. Bills */
16*69ae808eSJason M. Bills 
17*69ae808eSJason M. Bills #include <systemd/sd-journal.h>
18*69ae808eSJason M. Bills 
19*69ae808eSJason M. Bills #include <boost/algorithm/string/predicate.hpp>
20*69ae808eSJason M. Bills #include <boost/asio/io_context.hpp>
21*69ae808eSJason M. Bills #include <boost/asio/steady_timer.hpp>
22*69ae808eSJason M. Bills #include <boost/container/flat_map.hpp>
23*69ae808eSJason M. Bills #include <sdbusplus/asio/connection.hpp>
24*69ae808eSJason M. Bills #include <sdbusplus/bus.hpp>
25*69ae808eSJason M. Bills #include <sdbusplus/bus/match.hpp>
26*69ae808eSJason M. Bills 
27*69ae808eSJason M. Bills #include <cstdint>
28*69ae808eSJason M. Bills #include <iostream>
29*69ae808eSJason M. Bills #include <string>
30*69ae808eSJason M. Bills #include <variant>
31*69ae808eSJason M. Bills #include <vector>
32*69ae808eSJason M. Bills 
33*69ae808eSJason M. Bills using GetSubTreeType = std::vector<
34*69ae808eSJason M. Bills     std::pair<std::string,
35*69ae808eSJason M. Bills               std::vector<std::pair<std::string, std::vector<std::string>>>>>;
36*69ae808eSJason M. Bills using BasicVariantType =
37*69ae808eSJason M. Bills     std::variant<std::vector<std::string>, std::string, int64_t, uint64_t,
38*69ae808eSJason M. Bills                  double, int32_t, uint32_t, int16_t, uint16_t, uint8_t, bool>;
39*69ae808eSJason M. Bills using Association = std::tuple<std::string, std::string, std::string>;
40*69ae808eSJason M. Bills 
41*69ae808eSJason M. Bills constexpr const char* assetTag =
42*69ae808eSJason M. Bills     "xyz.openbmc_project.Inventory.Decorator.Asset";
43*69ae808eSJason M. Bills 
44*69ae808eSJason M. Bills namespace mapper
45*69ae808eSJason M. Bills {
46*69ae808eSJason M. Bills constexpr const char* busName = "xyz.openbmc_project.ObjectMapper";
47*69ae808eSJason M. Bills constexpr const char* path = "/xyz/openbmc_project/object_mapper";
48*69ae808eSJason M. Bills constexpr const char* interface = "xyz.openbmc_project.ObjectMapper";
49*69ae808eSJason M. Bills constexpr const char* subtree = "GetSubTree";
50*69ae808eSJason M. Bills } // namespace mapper
51*69ae808eSJason M. Bills 
52*69ae808eSJason M. Bills namespace entityManager
53*69ae808eSJason M. Bills {
54*69ae808eSJason M. Bills constexpr const char* busName = "xyz.openbmc_project.EntityManager";
55*69ae808eSJason M. Bills } // namespace entityManager
56*69ae808eSJason M. Bills 
57*69ae808eSJason M. Bills namespace inventory
58*69ae808eSJason M. Bills {
59*69ae808eSJason M. Bills constexpr const char* interface = "xyz.openbmc_project.Inventory.Item";
60*69ae808eSJason M. Bills } // namespace inventory
61*69ae808eSJason M. Bills 
62*69ae808eSJason M. Bills namespace ledGroup
63*69ae808eSJason M. Bills {
64*69ae808eSJason M. Bills constexpr const char* interface = "xyz.openbmc_project.Led.Group";
65*69ae808eSJason M. Bills constexpr const char* asserted = "Asserted";
66*69ae808eSJason M. Bills } // namespace ledGroup
67*69ae808eSJason M. Bills 
68*69ae808eSJason M. Bills namespace properties
69*69ae808eSJason M. Bills {
70*69ae808eSJason M. Bills constexpr const char* interface = "org.freedesktop.DBus.Properties";
71*69ae808eSJason M. Bills constexpr const char* get = "Get";
72*69ae808eSJason M. Bills } // namespace properties
73*69ae808eSJason M. Bills 
74*69ae808eSJason M. Bills namespace power
75*69ae808eSJason M. Bills {
76*69ae808eSJason M. Bills const static constexpr char* busname = "xyz.openbmc_project.State.Host";
77*69ae808eSJason M. Bills const static constexpr char* interface = "xyz.openbmc_project.State.Host";
78*69ae808eSJason M. Bills const static constexpr char* path = "/xyz/openbmc_project/state/host0";
79*69ae808eSJason M. Bills const static constexpr char* property = "CurrentHostState";
80*69ae808eSJason M. Bills } // namespace power
81*69ae808eSJason M. Bills 
82*69ae808eSJason M. Bills namespace association
83*69ae808eSJason M. Bills {
84*69ae808eSJason M. Bills const static constexpr char* interface =
85*69ae808eSJason M. Bills     "xyz.openbmc_project.Association.Definitions";
86*69ae808eSJason M. Bills } // namespace association
87*69ae808eSJason M. Bills 
88*69ae808eSJason M. Bills namespace hsbp
89*69ae808eSJason M. Bills {
90*69ae808eSJason M. Bills enum class registers : uint8_t
91*69ae808eSJason M. Bills {
92*69ae808eSJason M. Bills     fpgaIdH = 0x0,
93*69ae808eSJason M. Bills     fpgaIdL = 0x1,
94*69ae808eSJason M. Bills     typeId = 0x2,
95*69ae808eSJason M. Bills     bootVer = 0x3,
96*69ae808eSJason M. Bills     fpgaVer = 0x4,
97*69ae808eSJason M. Bills     securityRev = 0x5,
98*69ae808eSJason M. Bills     funSupported = 0x6,
99*69ae808eSJason M. Bills     numDisks = 0x7,
100*69ae808eSJason M. Bills     presence = 0x8,
101*69ae808eSJason M. Bills     ssdIFDET = 0x9,
102*69ae808eSJason M. Bills     ifdetPart = 0xA,
103*69ae808eSJason M. Bills     statusLocate = 0xB,
104*69ae808eSJason M. Bills     statusFail = 0xC,
105*69ae808eSJason M. Bills     statusRebuild = 0xD,
106*69ae808eSJason M. Bills     ledOverride = 0xE,
107*69ae808eSJason M. Bills     ledStatus = 0xF,
108*69ae808eSJason M. Bills     ledPattern0 = 0x10,
109*69ae808eSJason M. Bills     ledPattern1 = 0x11,
110*69ae808eSJason M. Bills     ledPattern2 = 0x12,
111*69ae808eSJason M. Bills     ledPattern3 = 0x13,
112*69ae808eSJason M. Bills     ledPattern4 = 0x14,
113*69ae808eSJason M. Bills     ledPattern5 = 0x15,
114*69ae808eSJason M. Bills     ledPattern6 = 0x16,
115*69ae808eSJason M. Bills     ledPattern7 = 0x17,
116*69ae808eSJason M. Bills };
117*69ae808eSJason M. Bills 
118*69ae808eSJason M. Bills } // namespace hsbp
119*69ae808eSJason M. Bills 
120*69ae808eSJason M. Bills static std::unique_ptr<sdbusplus::bus::match_t> powerMatch = nullptr;
121*69ae808eSJason M. Bills static bool powerStatusOn = false;
122*69ae808eSJason M. Bills 
isPowerOn(void)123*69ae808eSJason M. Bills bool isPowerOn(void)
124*69ae808eSJason M. Bills {
125*69ae808eSJason M. Bills     if (!powerMatch)
126*69ae808eSJason M. Bills     {
127*69ae808eSJason M. Bills         throw std::runtime_error("Power Match Not Created");
128*69ae808eSJason M. Bills     }
129*69ae808eSJason M. Bills     return powerStatusOn;
130*69ae808eSJason M. Bills }
131*69ae808eSJason M. Bills 
setupPowerMatch(const std::shared_ptr<sdbusplus::asio::connection> & conn)132*69ae808eSJason M. Bills void setupPowerMatch(const std::shared_ptr<sdbusplus::asio::connection>& conn)
133*69ae808eSJason M. Bills {
134*69ae808eSJason M. Bills     static boost::asio::steady_timer timer(conn->get_io_context());
135*69ae808eSJason M. Bills     // create a match for powergood changes, first time do a method call to
136*69ae808eSJason M. Bills     // cache the correct value
137*69ae808eSJason M. Bills     if (powerMatch)
138*69ae808eSJason M. Bills     {
139*69ae808eSJason M. Bills         return;
140*69ae808eSJason M. Bills     }
141*69ae808eSJason M. Bills 
142*69ae808eSJason M. Bills     powerMatch = std::make_unique<sdbusplus::bus::match_t>(
143*69ae808eSJason M. Bills         static_cast<sdbusplus::bus_t&>(*conn),
144*69ae808eSJason M. Bills         "type='signal',interface='" + std::string(properties::interface) +
145*69ae808eSJason M. Bills             "',path='" + std::string(power::path) + "',arg0='" +
146*69ae808eSJason M. Bills             std::string(power::interface) + "'",
147*69ae808eSJason M. Bills         [](sdbusplus::message_t& message) {
148*69ae808eSJason M. Bills             std::string objectName;
149*69ae808eSJason M. Bills             boost::container::flat_map<std::string, std::variant<std::string>>
150*69ae808eSJason M. Bills                 values;
151*69ae808eSJason M. Bills             message.read(objectName, values);
152*69ae808eSJason M. Bills             auto findState = values.find(power::property);
153*69ae808eSJason M. Bills             if (findState != values.end())
154*69ae808eSJason M. Bills             {
155*69ae808eSJason M. Bills                 bool on = boost::ends_with(
156*69ae808eSJason M. Bills                     std::get<std::string>(findState->second), "Running");
157*69ae808eSJason M. Bills                 if (!on)
158*69ae808eSJason M. Bills                 {
159*69ae808eSJason M. Bills                     timer.cancel();
160*69ae808eSJason M. Bills                     powerStatusOn = false;
161*69ae808eSJason M. Bills                     return;
162*69ae808eSJason M. Bills                 }
163*69ae808eSJason M. Bills                 // on comes too quickly
164*69ae808eSJason M. Bills                 timer.expires_after(std::chrono::seconds(10));
165*69ae808eSJason M. Bills                 timer.async_wait([](boost::system::error_code ec) {
166*69ae808eSJason M. Bills                     if (ec == boost::asio::error::operation_aborted)
167*69ae808eSJason M. Bills                     {
168*69ae808eSJason M. Bills                         return;
169*69ae808eSJason M. Bills                     }
170*69ae808eSJason M. Bills                     else if (ec)
171*69ae808eSJason M. Bills                     {
172*69ae808eSJason M. Bills                         std::cerr << "Timer error " << ec.message() << "\n";
173*69ae808eSJason M. Bills                         return;
174*69ae808eSJason M. Bills                     }
175*69ae808eSJason M. Bills                     powerStatusOn = true;
176*69ae808eSJason M. Bills                 });
177*69ae808eSJason M. Bills             }
178*69ae808eSJason M. Bills         });
179*69ae808eSJason M. Bills 
180*69ae808eSJason M. Bills     conn->async_method_call(
181*69ae808eSJason M. Bills         [](boost::system::error_code ec,
182*69ae808eSJason M. Bills            const std::variant<std::string>& state) {
183*69ae808eSJason M. Bills             if (ec)
184*69ae808eSJason M. Bills             {
185*69ae808eSJason M. Bills                 // we commonly come up before power control, we'll capture the
186*69ae808eSJason M. Bills                 // property change later
187*69ae808eSJason M. Bills                 return;
188*69ae808eSJason M. Bills             }
189*69ae808eSJason M. Bills             powerStatusOn =
190*69ae808eSJason M. Bills                 boost::ends_with(std::get<std::string>(state), "Running");
191*69ae808eSJason M. Bills         },
192*69ae808eSJason M. Bills         power::busname, power::path, properties::interface, properties::get,
193*69ae808eSJason M. Bills         power::interface, power::property);
194*69ae808eSJason M. Bills }
195*69ae808eSJason M. Bills 
logDeviceAdded(const std::string & model,const std::string & type,const std::string & sn)196*69ae808eSJason M. Bills inline void logDeviceAdded(const std::string& model, const std::string& type,
197*69ae808eSJason M. Bills                            const std::string& sn)
198*69ae808eSJason M. Bills {
199*69ae808eSJason M. Bills     sd_journal_send("MESSAGE=%s", "Inventory Added", "PRIORITY=%i", LOG_ERR,
200*69ae808eSJason M. Bills                     "REDFISH_MESSAGE_ID=%s", "OpenBMC.0.1.InventoryAdded",
201*69ae808eSJason M. Bills                     "REDFISH_MESSAGE_ARGS=%s,%s,%s", model.c_str(),
202*69ae808eSJason M. Bills                     type.c_str(), sn.c_str(), NULL);
203*69ae808eSJason M. Bills }
204*69ae808eSJason M. Bills 
logDeviceRemoved(const std::string & model,const std::string & type,const std::string & sn)205*69ae808eSJason M. Bills inline void logDeviceRemoved(const std::string& model, const std::string& type,
206*69ae808eSJason M. Bills                              const std::string& sn)
207*69ae808eSJason M. Bills {
208*69ae808eSJason M. Bills     sd_journal_send("MESSAGE=%s", "Inventory Removed", "PRIORITY=%i", LOG_ERR,
209*69ae808eSJason M. Bills                     "REDFISH_MESSAGE_ID=%s", "OpenBMC.0.1.InventoryRemoved",
210*69ae808eSJason M. Bills                     "REDFISH_MESSAGE_ARGS=%s,%s,%s", model.c_str(),
211*69ae808eSJason M. Bills                     type.c_str(), sn.c_str(), NULL);
212*69ae808eSJason M. Bills }
213*69ae808eSJason M. Bills 
logDriveError(const std::string & name)214*69ae808eSJason M. Bills inline void logDriveError(const std::string& name)
215*69ae808eSJason M. Bills {
216*69ae808eSJason M. Bills     sd_journal_send("MESSAGE=%s", "Drive Error", "PRIORITY=%i", LOG_ERR,
217*69ae808eSJason M. Bills                     "REDFISH_MESSAGE_ID=%s", "OpenBMC.0.1.DriveError",
218*69ae808eSJason M. Bills                     "REDFISH_MESSAGE_ARGS=%s", name.c_str(), NULL);
219*69ae808eSJason M. Bills }
220