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
17e881852bSJames Feist #include <systemd/sd-journal.h>
18e881852bSJames 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>
26*ff1c36e5SPatrick Williams #include <sdbusplus/bus.hpp>
2726067f6aSJonathan Doman #include <sdbusplus/bus/match.hpp>
28c95cf671SFeist, James #include <string>
29c95cf671SFeist, James #include <variant>
30c95cf671SFeist, James #include <vector>
31c95cf671SFeist, James
32c95cf671SFeist, James using GetSubTreeType = std::vector<
33c95cf671SFeist, James std::pair<std::string,
34c95cf671SFeist, James std::vector<std::pair<std::string, std::vector<std::string>>>>>;
35c95cf671SFeist, James using BasicVariantType =
36c95cf671SFeist, James std::variant<std::vector<std::string>, std::string, int64_t, uint64_t,
37c95cf671SFeist, James double, int32_t, uint32_t, int16_t, uint16_t, uint8_t, bool>;
380b236ab8SJames Feist using Association = std::tuple<std::string, std::string, std::string>;
39c95cf671SFeist, James
40d0d36f10SJames Feist constexpr const char* assetTag =
41d0d36f10SJames Feist "xyz.openbmc_project.Inventory.Decorator.Asset";
42d0d36f10SJames Feist
43c95cf671SFeist, James namespace mapper
44c95cf671SFeist, James {
45c95cf671SFeist, James constexpr const char* busName = "xyz.openbmc_project.ObjectMapper";
46c95cf671SFeist, James constexpr const char* path = "/xyz/openbmc_project/object_mapper";
47c95cf671SFeist, James constexpr const char* interface = "xyz.openbmc_project.ObjectMapper";
48c95cf671SFeist, James constexpr const char* subtree = "GetSubTree";
49c95cf671SFeist, James } // namespace mapper
50c95cf671SFeist, James
51c95cf671SFeist, James namespace entityManager
52c95cf671SFeist, James {
53c95cf671SFeist, James constexpr const char* busName = "xyz.openbmc_project.EntityManager";
54c95cf671SFeist, James } // namespace entityManager
55c95cf671SFeist, James
56c95cf671SFeist, James namespace inventory
57c95cf671SFeist, James {
58c95cf671SFeist, James constexpr const char* interface = "xyz.openbmc_project.Inventory.Item";
59c95cf671SFeist, James } // namespace inventory
60c95cf671SFeist, James
6109dd2314SJames Feist namespace ledGroup
6209dd2314SJames Feist {
6309dd2314SJames Feist constexpr const char* interface = "xyz.openbmc_project.Led.Group";
6409dd2314SJames Feist constexpr const char* asserted = "Asserted";
6509dd2314SJames Feist } // namespace ledGroup
6609dd2314SJames Feist
679f6565dbSJames Feist namespace properties
689f6565dbSJames Feist {
699f6565dbSJames Feist constexpr const char* interface = "org.freedesktop.DBus.Properties";
709f6565dbSJames Feist constexpr const char* get = "Get";
719f6565dbSJames Feist } // namespace properties
729f6565dbSJames Feist
739f6565dbSJames Feist namespace power
749f6565dbSJames Feist {
759f6565dbSJames Feist const static constexpr char* busname = "xyz.openbmc_project.State.Host";
769f6565dbSJames Feist const static constexpr char* interface = "xyz.openbmc_project.State.Host";
779f6565dbSJames Feist const static constexpr char* path = "/xyz/openbmc_project/state/host0";
789f6565dbSJames Feist const static constexpr char* property = "CurrentHostState";
799f6565dbSJames Feist } // namespace power
809f6565dbSJames Feist
8142b49c17SJames Feist namespace association
8242b49c17SJames Feist {
8342b49c17SJames Feist const static constexpr char* interface =
8442b49c17SJames Feist "xyz.openbmc_project.Association.Definitions";
8542b49c17SJames Feist } // namespace association
8642b49c17SJames Feist
87c95cf671SFeist, James namespace hsbp
88c95cf671SFeist, James {
89c95cf671SFeist, James enum class registers : uint8_t
90c95cf671SFeist, James {
91c95cf671SFeist, James fpgaIdH = 0x0,
92c95cf671SFeist, James fpgaIdL = 0x1,
93c95cf671SFeist, James typeId = 0x2,
94c95cf671SFeist, James bootVer = 0x3,
95c95cf671SFeist, James fpgaVer = 0x4,
96c95cf671SFeist, James securityRev = 0x5,
97c95cf671SFeist, James funSupported = 0x6,
98c95cf671SFeist, James numDisks = 0x7,
99c95cf671SFeist, James presence = 0x8,
100c95cf671SFeist, James ssdIFDET = 0x9,
101c95cf671SFeist, James ifdetPart = 0xA,
102c95cf671SFeist, James statusLocate = 0xB,
103c95cf671SFeist, James statusFail = 0xC,
104c95cf671SFeist, James statusRebuild = 0xD,
105c95cf671SFeist, James ledOverride = 0xE,
106c95cf671SFeist, James ledStatus = 0xF,
107c95cf671SFeist, James ledPattern0 = 0x10,
108c95cf671SFeist, James ledPattern1 = 0x11,
109c95cf671SFeist, James ledPattern2 = 0x12,
110c95cf671SFeist, James ledPattern3 = 0x13,
111c95cf671SFeist, James ledPattern4 = 0x14,
112c95cf671SFeist, James ledPattern5 = 0x15,
113c95cf671SFeist, James ledPattern6 = 0x16,
114c95cf671SFeist, James ledPattern7 = 0x17,
115c95cf671SFeist, James };
116c95cf671SFeist, James
117c95cf671SFeist, James } // namespace hsbp
1189f6565dbSJames Feist
11926067f6aSJonathan Doman static std::unique_ptr<sdbusplus::bus::match_t> powerMatch = nullptr;
1209f6565dbSJames Feist static bool powerStatusOn = false;
1219f6565dbSJames Feist
isPowerOn(void)1229f6565dbSJames Feist bool isPowerOn(void)
1239f6565dbSJames Feist {
1249f6565dbSJames Feist if (!powerMatch)
1259f6565dbSJames Feist {
1269f6565dbSJames Feist throw std::runtime_error("Power Match Not Created");
1279f6565dbSJames Feist }
1289f6565dbSJames Feist return powerStatusOn;
1299f6565dbSJames Feist }
1309f6565dbSJames Feist
setupPowerMatch(const std::shared_ptr<sdbusplus::asio::connection> & conn)1319f6565dbSJames Feist void setupPowerMatch(const std::shared_ptr<sdbusplus::asio::connection>& conn)
1329f6565dbSJames Feist {
1339f6565dbSJames Feist static boost::asio::steady_timer timer(conn->get_io_context());
1349f6565dbSJames Feist // create a match for powergood changes, first time do a method call to
1359f6565dbSJames Feist // cache the correct value
1369f6565dbSJames Feist if (powerMatch)
1379f6565dbSJames Feist {
1389f6565dbSJames Feist return;
1399f6565dbSJames Feist }
1409f6565dbSJames Feist
14126067f6aSJonathan Doman powerMatch = std::make_unique<sdbusplus::bus::match_t>(
142*ff1c36e5SPatrick Williams static_cast<sdbusplus::bus_t&>(*conn),
1439f6565dbSJames Feist "type='signal',interface='" + std::string(properties::interface) +
1449f6565dbSJames Feist "',path='" + std::string(power::path) + "',arg0='" +
1459f6565dbSJames Feist std::string(power::interface) + "'",
146*ff1c36e5SPatrick Williams [](sdbusplus::message_t& message) {
1479f6565dbSJames Feist std::string objectName;
1489f6565dbSJames Feist boost::container::flat_map<std::string, std::variant<std::string>>
1499f6565dbSJames Feist values;
1509f6565dbSJames Feist message.read(objectName, values);
1519f6565dbSJames Feist auto findState = values.find(power::property);
1529f6565dbSJames Feist if (findState != values.end())
1539f6565dbSJames Feist {
1549f6565dbSJames Feist bool on = boost::ends_with(
1559f6565dbSJames Feist std::get<std::string>(findState->second), "Running");
1569f6565dbSJames Feist if (!on)
1579f6565dbSJames Feist {
1589f6565dbSJames Feist timer.cancel();
1599f6565dbSJames Feist powerStatusOn = false;
1609f6565dbSJames Feist return;
1619f6565dbSJames Feist }
1629f6565dbSJames Feist // on comes too quickly
1639f6565dbSJames Feist timer.expires_after(std::chrono::seconds(10));
1649f6565dbSJames Feist timer.async_wait([](boost::system::error_code ec) {
1659f6565dbSJames Feist if (ec == boost::asio::error::operation_aborted)
1669f6565dbSJames Feist {
1679f6565dbSJames Feist return;
1689f6565dbSJames Feist }
1699f6565dbSJames Feist else if (ec)
1709f6565dbSJames Feist {
1719f6565dbSJames Feist std::cerr << "Timer error " << ec.message() << "\n";
1729f6565dbSJames Feist return;
1739f6565dbSJames Feist }
1749f6565dbSJames Feist powerStatusOn = true;
1759f6565dbSJames Feist });
1769f6565dbSJames Feist }
1779f6565dbSJames Feist });
1789f6565dbSJames Feist
1799f6565dbSJames Feist conn->async_method_call(
1809f6565dbSJames Feist [](boost::system::error_code ec,
1819f6565dbSJames Feist const std::variant<std::string>& state) {
1829f6565dbSJames Feist if (ec)
1839f6565dbSJames Feist {
1849f6565dbSJames Feist // we commonly come up before power control, we'll capture the
1859f6565dbSJames Feist // property change later
1869f6565dbSJames Feist return;
1879f6565dbSJames Feist }
1889f6565dbSJames Feist powerStatusOn =
1899f6565dbSJames Feist boost::ends_with(std::get<std::string>(state), "Running");
1909f6565dbSJames Feist },
1919f6565dbSJames Feist power::busname, power::path, properties::interface, properties::get,
1929f6565dbSJames Feist power::interface, power::property);
1939f6565dbSJames Feist }
194e881852bSJames Feist
logDeviceAdded(const std::string & model,const std::string & type,const std::string & sn)195e881852bSJames Feist inline void logDeviceAdded(const std::string& model, const std::string& type,
196e881852bSJames Feist const std::string& sn)
197e881852bSJames Feist {
198e881852bSJames Feist sd_journal_send("MESSAGE=%s", "Inventory Added", "PRIORITY=%i", LOG_ERR,
199e881852bSJames Feist "REDFISH_MESSAGE_ID=%s", "OpenBMC.0.1.InventoryAdded",
200e881852bSJames Feist "REDFISH_MESSAGE_ARGS=%s,%s,%s", model.c_str(),
201e881852bSJames Feist type.c_str(), sn.c_str(), NULL);
202e881852bSJames Feist }
203e881852bSJames Feist
logDeviceRemoved(const std::string & model,const std::string & type,const std::string & sn)204e881852bSJames Feist inline void logDeviceRemoved(const std::string& model, const std::string& type,
205e881852bSJames Feist const std::string& sn)
206e881852bSJames Feist {
207e881852bSJames Feist sd_journal_send("MESSAGE=%s", "Inventory Removed", "PRIORITY=%i", LOG_ERR,
208e881852bSJames Feist "REDFISH_MESSAGE_ID=%s", "OpenBMC.0.1.InventoryRemoved",
209e881852bSJames Feist "REDFISH_MESSAGE_ARGS=%s,%s,%s", model.c_str(),
210e881852bSJames Feist type.c_str(), sn.c_str(), NULL);
211e881852bSJames Feist }
212e881852bSJames Feist
logDriveError(const std::string & name)213e881852bSJames Feist inline void logDriveError(const std::string& name)
214e881852bSJames Feist {
215e881852bSJames Feist sd_journal_send("MESSAGE=%s", "Drive Error", "PRIORITY=%i", LOG_ERR,
216e881852bSJames Feist "REDFISH_MESSAGE_ID=%s", "OpenBMC.0.1.DriveError",
217e881852bSJames Feist "REDFISH_MESSAGE_ARGS=%s", name.c_str(), NULL);
218e881852bSJames Feist }
219