xref: /openbmc/phosphor-host-ipmid/chassishandler.cpp (revision 8c1376cae73da401d40e1c7f07e6f830bd544a21)
146470a38SPatrick Venture #include "config.h"
246470a38SPatrick Venture 
346470a38SPatrick Venture #include "chassishandler.hpp"
40b02be92SPatrick Venture 
50b02be92SPatrick Venture #include <arpa/inet.h>
60b02be92SPatrick Venture #include <endian.h>
70b02be92SPatrick Venture #include <limits.h>
80b02be92SPatrick Venture #include <netinet/in.h>
90b02be92SPatrick Venture 
10e08fbffcSVernon Mauery #include <ipmid/api.hpp>
1133250240SVernon Mauery #include <ipmid/types.hpp>
126a98fe7fSVernon Mauery #include <ipmid/utils.hpp>
133a5071a9SPatrick Venture #include <phosphor-logging/elog-errors.hpp>
1438108d9dSVernon Mauery #include <phosphor-logging/lg2.hpp>
153a5071a9SPatrick Venture #include <sdbusplus/bus.hpp>
164c008028SWilliam A. Kennington III #include <sdbusplus/message/types.hpp>
173a5071a9SPatrick Venture #include <sdbusplus/server/object.hpp>
181181af74SVernon Mauery #include <sdbusplus/timer.hpp>
19e278ead0SVernon Mauery #include <settings.hpp>
20*8c1376caSChau Ly #include <xyz/openbmc_project/Chassis/Intrusion/client.hpp>
213a5071a9SPatrick Venture #include <xyz/openbmc_project/Common/error.hpp>
223a5071a9SPatrick Venture #include <xyz/openbmc_project/Control/Boot/Mode/server.hpp>
233a5071a9SPatrick Venture #include <xyz/openbmc_project/Control/Boot/Source/server.hpp>
2496ef0282SKonstantin Aladyshev #include <xyz/openbmc_project/Control/Boot/Type/server.hpp>
253a5071a9SPatrick Venture #include <xyz/openbmc_project/Control/Power/RestorePolicy/server.hpp>
26ad588bf5SJason M. Bills #include <xyz/openbmc_project/State/Chassis/server.hpp>
273a5071a9SPatrick Venture #include <xyz/openbmc_project/State/Host/server.hpp>
283a5071a9SPatrick Venture #include <xyz/openbmc_project/State/PowerOnHours/server.hpp>
293a5071a9SPatrick Venture 
30fbc6c9d7SPatrick Williams #include <array>
31fbc6c9d7SPatrick Williams #include <chrono>
32fbc6c9d7SPatrick Williams #include <cstring>
33fbc6c9d7SPatrick Williams #include <filesystem>
34fbc6c9d7SPatrick Williams #include <fstream>
35fbc6c9d7SPatrick Williams #include <future>
36fbc6c9d7SPatrick Williams #include <map>
37fbc6c9d7SPatrick Williams #include <sstream>
38fbc6c9d7SPatrick Williams #include <string>
39fbc6c9d7SPatrick Williams 
4095655220SPatrick Williams std::unique_ptr<sdbusplus::Timer> identifyTimer
414b0ddb68SLei YU     __attribute__((init_priority(101)));
426706c1ccSMarri Devender Rao 
43f4e38515SYong Li static ChassisIDState chassisIDState = ChassisIDState::reserved;
44f4e38515SYong Li 
45bfd8fc4bSjayaprakash Mutyala constexpr size_t sizeVersion = 2;
465110c125STom Joseph constexpr size_t DEFAULT_IDENTIFY_TIME_OUT = 15;
476ec7daabSRatan Gupta 
48fd28dd7aSRatan Gupta // PetiBoot-Specific
49bfd8fc4bSjayaprakash Mutyala static constexpr uint8_t netConfInitialBytes[] = {0x80, 0x21, 0x70, 0x62,
506ec7daabSRatan Gupta                                                   0x21, 0x00, 0x01, 0x06};
51bfd8fc4bSjayaprakash Mutyala static constexpr uint8_t oemParmStart = 96;
52bfd8fc4bSjayaprakash Mutyala static constexpr uint8_t oemParmEnd = 127;
53fd28dd7aSRatan Gupta 
54bfd8fc4bSjayaprakash Mutyala static constexpr size_t cookieOffset = 1;
55bfd8fc4bSjayaprakash Mutyala static constexpr size_t versionOffset = 5;
56bfd8fc4bSjayaprakash Mutyala static constexpr size_t addrSizeOffset = 8;
57bfd8fc4bSjayaprakash Mutyala static constexpr size_t macOffset = 9;
58bfd8fc4bSjayaprakash Mutyala static constexpr size_t addrTypeOffset = 16;
59bfd8fc4bSjayaprakash Mutyala static constexpr size_t ipAddrOffset = 17;
6098a23840SMatthew Barth 
61bfd8fc4bSjayaprakash Mutyala namespace ipmi
62bfd8fc4bSjayaprakash Mutyala {
63bfd8fc4bSjayaprakash Mutyala constexpr Cc ccParmNotSupported = 0x80;
64bfd8fc4bSjayaprakash Mutyala 
responseParmNotSupported()65bfd8fc4bSjayaprakash Mutyala static inline auto responseParmNotSupported()
66bfd8fc4bSjayaprakash Mutyala {
67bfd8fc4bSjayaprakash Mutyala     return response(ccParmNotSupported);
68bfd8fc4bSjayaprakash Mutyala }
69bfd8fc4bSjayaprakash Mutyala } // namespace ipmi
70bfd8fc4bSjayaprakash Mutyala 
715087b075SGeorge Liu void registerNetFnChassisFunctions() __attribute__((constructor));
7298a23840SMatthew Barth 
7398a23840SMatthew Barth // Host settings in dbus
7498a23840SMatthew Barth // Service name should be referenced by connection name got via object mapper
7598a23840SMatthew Barth const char* settings_object_name = "/org/openbmc/settings/host0";
7698a23840SMatthew Barth const char* settings_intf_name = "org.freedesktop.DBus.Properties";
775110c125STom Joseph const char* identify_led_object_name =
785110c125STom Joseph     "/xyz/openbmc_project/led/groups/enclosure_identify";
7998a23840SMatthew Barth 
80dcb10671SRatan Gupta constexpr auto SETTINGS_ROOT = "/";
81dcb10671SRatan Gupta constexpr auto SETTINGS_MATCH = "host0";
82dcb10671SRatan Gupta 
83dcb10671SRatan Gupta constexpr auto IP_INTERFACE = "xyz.openbmc_project.Network.IP";
84dcb10671SRatan Gupta constexpr auto MAC_INTERFACE = "xyz.openbmc_project.Network.MACAddress";
85dcb10671SRatan Gupta 
86a59d83f8SNagaraju Goruganti static constexpr auto chassisStateRoot = "/xyz/openbmc_project/state";
87a59d83f8SNagaraju Goruganti static constexpr auto chassisPOHStateIntf =
88a59d83f8SNagaraju Goruganti     "xyz.openbmc_project.State.PowerOnHours";
897345ac41SPatrick Williams static constexpr auto pohCounterProperty = "POHCounter";
90a59d83f8SNagaraju Goruganti static constexpr auto match = "chassis0";
91ae4b040bSYong Li const static constexpr char chassisCapIntf[] =
92ae4b040bSYong Li     "xyz.openbmc_project.Control.ChassisCapabilities";
9386d8bd79SKarthick Sundarrajan const static constexpr char chassisIntrusionProp[] = "ChassisIntrusionEnabled";
9486d8bd79SKarthick Sundarrajan const static constexpr char chassisFrontPanelLockoutProp[] =
9586d8bd79SKarthick Sundarrajan     "ChassisFrontPanelLockoutEnabled";
9686d8bd79SKarthick Sundarrajan const static constexpr char chassisNMIProp[] = "ChassisNMIEnabled";
9786d8bd79SKarthick Sundarrajan const static constexpr char chassisPowerInterlockProp[] =
9886d8bd79SKarthick Sundarrajan     "ChassisPowerInterlockEnabled";
99ae4b040bSYong Li const static constexpr char chassisFRUDevAddrProp[] = "FRUDeviceAddress";
100ae4b040bSYong Li const static constexpr char chassisSDRDevAddrProp[] = "SDRDeviceAddress";
101ae4b040bSYong Li const static constexpr char chassisSELDevAddrProp[] = "SELDeviceAddress";
102ae4b040bSYong Li const static constexpr char chassisSMDevAddrProp[] = "SMDeviceAddress";
103ae4b040bSYong Li const static constexpr char chassisBridgeDevAddrProp[] = "BridgeDeviceAddress";
104ae4b040bSYong Li static constexpr uint8_t chassisCapAddrMask = 0xfe;
1054a8a4eb9SVernon Mauery static constexpr const char* powerButtonIntf =
1064a8a4eb9SVernon Mauery     "xyz.openbmc_project.Chassis.Buttons.Power";
1074a8a4eb9SVernon Mauery static constexpr const char* powerButtonPath =
1084a8a4eb9SVernon Mauery     "/xyz/openbmc_project/Chassis/Buttons/Power0";
1094a8a4eb9SVernon Mauery static constexpr const char* resetButtonIntf =
1104a8a4eb9SVernon Mauery     "xyz.openbmc_project.Chassis.Buttons.Reset";
1114a8a4eb9SVernon Mauery static constexpr const char* resetButtonPath =
1124a8a4eb9SVernon Mauery     "/xyz/openbmc_project/Chassis/Buttons/Reset0";
113dcb10671SRatan Gupta 
114b12b0c01SVishwanatha Subbanna // Phosphor Host State manager
115523e2d1bSWilly Tu namespace State = sdbusplus::server::xyz::openbmc_project::state;
116185b9f8bSVernon Mauery namespace fs = std::filesystem;
117a6e3a308SAndrew Geissler 
118dcb10671SRatan Gupta using namespace phosphor::logging;
119523e2d1bSWilly Tu using namespace sdbusplus::error::xyz::openbmc_project::common;
120523e2d1bSWilly Tu using namespace sdbusplus::server::xyz::openbmc_project::control::boot;
121*8c1376caSChau Ly using Intrusion = sdbusplus::client::xyz::openbmc_project::chassis::Intrusion<>;
1224c008028SWilliam A. Kennington III 
1238cc19362SDeepak Kodihalli namespace chassis
1248cc19362SDeepak Kodihalli {
1258cc19362SDeepak Kodihalli namespace internal
1268cc19362SDeepak Kodihalli {
1278cc19362SDeepak Kodihalli 
12808a080abSKonstantin Aladyshev constexpr auto bootSettingsPath = "/xyz/openbmc_project/control/host0/boot";
12908a080abSKonstantin Aladyshev constexpr auto bootEnableIntf = "xyz.openbmc_project.Object.Enable";
1308cc19362SDeepak Kodihalli constexpr auto bootModeIntf = "xyz.openbmc_project.Control.Boot.Mode";
13196ef0282SKonstantin Aladyshev constexpr auto bootTypeIntf = "xyz.openbmc_project.Control.Boot.Type";
1328cc19362SDeepak Kodihalli constexpr auto bootSourceIntf = "xyz.openbmc_project.Control.Boot.Source";
13308a080abSKonstantin Aladyshev constexpr auto bootSettingsOneTimePath =
13408a080abSKonstantin Aladyshev     "/xyz/openbmc_project/control/host0/boot/one_time";
13508a080abSKonstantin Aladyshev constexpr auto bootOneTimeIntf = "xyz.openbmc_project.Object.Enable";
13608a080abSKonstantin Aladyshev 
13718b70d11SDeepak Kodihalli constexpr auto powerRestoreIntf =
13818b70d11SDeepak Kodihalli     "xyz.openbmc_project.Control.Power.RestorePolicy";
1395d82f474SPatrick Williams sdbusplus::bus_t dbus(ipmid_get_sd_bus_connection());
1408cc19362SDeepak Kodihalli 
1418cc19362SDeepak Kodihalli namespace cache
1428cc19362SDeepak Kodihalli {
1438cc19362SDeepak Kodihalli 
144225dec85SJames Feist std::unique_ptr<settings::Objects> objectsPtr = nullptr;
145225dec85SJames Feist 
getObjects()146225dec85SJames Feist settings::Objects& getObjects()
147225dec85SJames Feist {
148225dec85SJames Feist     if (objectsPtr == nullptr)
149225dec85SJames Feist     {
150225dec85SJames Feist         objectsPtr = std::make_unique<settings::Objects>(
15196ef0282SKonstantin Aladyshev             dbus, std::vector<std::string>{bootModeIntf, bootTypeIntf,
15296ef0282SKonstantin Aladyshev                                            bootSourceIntf, powerRestoreIntf});
153225dec85SJames Feist     }
154225dec85SJames Feist     return *objectsPtr;
155225dec85SJames Feist }
1568cc19362SDeepak Kodihalli 
1578cc19362SDeepak Kodihalli } // namespace cache
1588cc19362SDeepak Kodihalli } // namespace internal
1598cc19362SDeepak Kodihalli } // namespace chassis
1608cc19362SDeepak Kodihalli 
161a59d83f8SNagaraju Goruganti namespace poh
162a59d83f8SNagaraju Goruganti {
163a59d83f8SNagaraju Goruganti 
164a59d83f8SNagaraju Goruganti constexpr auto minutesPerCount = 60;
165a59d83f8SNagaraju Goruganti 
166a59d83f8SNagaraju Goruganti } // namespace poh
167a59d83f8SNagaraju Goruganti 
getHostNetworkData(ipmi::message::Payload & payload)168d1ef877fSJayaprakash Mutyala int getHostNetworkData(ipmi::message::Payload& payload)
169fd28dd7aSRatan Gupta {
170dcb10671SRatan Gupta     ipmi::PropertyMap properties;
171dcb10671SRatan Gupta     int rc = 0;
1728c31d237SRatan Gupta     uint8_t addrSize = ipmi::network::IPV4_ADDRESS_SIZE_BYTE;
173fd28dd7aSRatan Gupta 
174dcb10671SRatan Gupta     try
175dcb10671SRatan Gupta     {
176dcb10671SRatan Gupta         // TODO There may be cases where an interface is implemented by multiple
177dcb10671SRatan Gupta         // objects,to handle such cases we are interested on that object
178dcb10671SRatan Gupta         //  which are on interested busname.
179dcb10671SRatan Gupta         //  Currenlty mapper doesn't give the readable busname(gives busid)
180dcb10671SRatan Gupta         //  so we can't match with bus name so giving some object specific info
181dcb10671SRatan Gupta         //  as SETTINGS_MATCH.
182dcb10671SRatan Gupta         //  Later SETTINGS_MATCH will be replaced with busname.
183fd28dd7aSRatan Gupta 
1845d82f474SPatrick Williams         sdbusplus::bus_t bus(ipmid_get_sd_bus_connection());
185fd28dd7aSRatan Gupta 
18601d4bd1aSRatan Gupta         auto ipObjectInfo = ipmi::getDbusObject(bus, IP_INTERFACE,
18701d4bd1aSRatan Gupta                                                 SETTINGS_ROOT, SETTINGS_MATCH);
18801d4bd1aSRatan Gupta 
18901d4bd1aSRatan Gupta         auto macObjectInfo = ipmi::getDbusObject(bus, MAC_INTERFACE,
19001d4bd1aSRatan Gupta                                                  SETTINGS_ROOT, SETTINGS_MATCH);
19101d4bd1aSRatan Gupta 
1920b02be92SPatrick Venture         properties = ipmi::getAllDbusProperties(
1930b02be92SPatrick Venture             bus, ipObjectInfo.second, ipObjectInfo.first, IP_INTERFACE);
1941318a5edSPatrick Williams         auto variant = ipmi::getDbusProperty(
1951318a5edSPatrick Williams             bus, macObjectInfo.second, macObjectInfo.first, MAC_INTERFACE,
1960b02be92SPatrick Venture             "MACAddress");
197fd28dd7aSRatan Gupta 
198f442e119SVernon Mauery         auto ipAddress = std::get<std::string>(properties["Address"]);
199d70f4534SRatan Gupta 
200f442e119SVernon Mauery         auto gateway = std::get<std::string>(properties["Gateway"]);
201d70f4534SRatan Gupta 
202f442e119SVernon Mauery         auto prefix = std::get<uint8_t>(properties["PrefixLength"]);
203d70f4534SRatan Gupta 
2040b02be92SPatrick Venture         uint8_t isStatic =
205f442e119SVernon Mauery             (std::get<std::string>(properties["Origin"]) ==
206d70f4534SRatan Gupta              "xyz.openbmc_project.Network.IP.AddressOrigin.Static")
2070b02be92SPatrick Venture                 ? 1
2080b02be92SPatrick Venture                 : 0;
209d70f4534SRatan Gupta 
210f442e119SVernon Mauery         auto MACAddress = std::get<std::string>(variant);
211cc8feb4fSRatan Gupta 
212d70f4534SRatan Gupta         // it is expected here that we should get the valid data
213d70f4534SRatan Gupta         // but we may also get the default values.
214d70f4534SRatan Gupta         // Validation of the data is done by settings.
215d70f4534SRatan Gupta         //
216d70f4534SRatan Gupta         // if mac address is default mac address then
217d70f4534SRatan Gupta         // don't send blank override.
2188c31d237SRatan Gupta         if ((MACAddress == ipmi::network::DEFAULT_MAC_ADDRESS))
219d70f4534SRatan Gupta         {
220d70f4534SRatan Gupta             rc = -1;
221d70f4534SRatan Gupta             return rc;
222d70f4534SRatan Gupta         }
223d70f4534SRatan Gupta         // if addr is static then ipaddress,gateway,prefix
224d70f4534SRatan Gupta         // should not be default one,don't send blank override.
225d70f4534SRatan Gupta         if (isStatic)
226d70f4534SRatan Gupta         {
2278c31d237SRatan Gupta             if ((ipAddress == ipmi::network::DEFAULT_ADDRESS) ||
2280b02be92SPatrick Venture                 (gateway == ipmi::network::DEFAULT_ADDRESS) || (!prefix))
229d70f4534SRatan Gupta             {
230d70f4534SRatan Gupta                 rc = -1;
231d70f4534SRatan Gupta                 return rc;
232d70f4534SRatan Gupta             }
233d70f4534SRatan Gupta         }
234d70f4534SRatan Gupta 
235d1ef877fSJayaprakash Mutyala         std::string token;
236d1ef877fSJayaprakash Mutyala         std::stringstream ss(MACAddress);
237fd28dd7aSRatan Gupta 
238d1ef877fSJayaprakash Mutyala         // First pack macOffset no of bytes in payload.
239d1ef877fSJayaprakash Mutyala         // Latter this PetiBoot-Specific data will be populated.
240d1ef877fSJayaprakash Mutyala         std::vector<uint8_t> payloadInitialBytes(macOffset);
241d1ef877fSJayaprakash Mutyala         payload.pack(payloadInitialBytes);
242fd28dd7aSRatan Gupta 
243d1ef877fSJayaprakash Mutyala         while (std::getline(ss, token, ':'))
244d1ef877fSJayaprakash Mutyala         {
245d1ef877fSJayaprakash Mutyala             payload.pack(stoi(token, nullptr, 16));
246d1ef877fSJayaprakash Mutyala         }
247d1ef877fSJayaprakash Mutyala 
248d1ef877fSJayaprakash Mutyala         payload.pack(0x00);
249d1ef877fSJayaprakash Mutyala 
250d1ef877fSJayaprakash Mutyala         payload.pack(isStatic);
2516ec7daabSRatan Gupta 
252f442e119SVernon Mauery         uint8_t addressFamily = (std::get<std::string>(properties["Type"]) ==
2530b02be92SPatrick Venture                                  "xyz.openbmc_project.Network.IP.Protocol.IPv4")
2540b02be92SPatrick Venture                                     ? AF_INET
2550b02be92SPatrick Venture                                     : AF_INET6;
2566ec7daabSRatan Gupta 
2570b02be92SPatrick Venture         addrSize = (addressFamily == AF_INET)
2580b02be92SPatrick Venture                        ? ipmi::network::IPV4_ADDRESS_SIZE_BYTE
2590b02be92SPatrick Venture                        : ipmi::network::IPV6_ADDRESS_SIZE_BYTE;
260fd28dd7aSRatan Gupta 
261fd28dd7aSRatan Gupta         // ipaddress and gateway would be in IPv4 format
262d1ef877fSJayaprakash Mutyala         std::vector<uint8_t> addrInBinary(addrSize);
263d70f4534SRatan Gupta         inet_pton(addressFamily, ipAddress.c_str(),
264d1ef877fSJayaprakash Mutyala                   reinterpret_cast<void*>(addrInBinary.data()));
265fd28dd7aSRatan Gupta 
266d1ef877fSJayaprakash Mutyala         payload.pack(addrInBinary);
2676ec7daabSRatan Gupta 
268d1ef877fSJayaprakash Mutyala         payload.pack(prefix);
2696ec7daabSRatan Gupta 
270d1ef877fSJayaprakash Mutyala         std::vector<uint8_t> gatewayDetails(addrSize);
271d70f4534SRatan Gupta         inet_pton(addressFamily, gateway.c_str(),
272d1ef877fSJayaprakash Mutyala                   reinterpret_cast<void*>(gatewayDetails.data()));
273d1ef877fSJayaprakash Mutyala         payload.pack(gatewayDetails);
274fd28dd7aSRatan Gupta     }
275a2ad2da8SPatrick Williams     catch (const InternalFailure& e)
276dcb10671SRatan Gupta     {
277dcb10671SRatan Gupta         commit<InternalFailure>();
278dcb10671SRatan Gupta         rc = -1;
279dcb10671SRatan Gupta         return rc;
280dcb10671SRatan Gupta     }
281fd28dd7aSRatan Gupta 
282fd28dd7aSRatan Gupta     // PetiBoot-Specific
283d1ef877fSJayaprakash Mutyala     // If success then copy the first 9 bytes to the payload message
284d1ef877fSJayaprakash Mutyala     // payload first 2 bytes contain the parameter values. Skip that 2 bytes.
285d1ef877fSJayaprakash Mutyala     uint8_t skipFirstTwoBytes = 2;
286d1ef877fSJayaprakash Mutyala     size_t payloadSize = payload.size();
287d1ef877fSJayaprakash Mutyala     uint8_t* configDataStartingAddress = payload.data() + skipFirstTwoBytes;
288fd28dd7aSRatan Gupta 
289d1ef877fSJayaprakash Mutyala     if (payloadSize < skipFirstTwoBytes + sizeof(netConfInitialBytes))
290d1ef877fSJayaprakash Mutyala     {
29138108d9dSVernon Mauery         lg2::error("Invalid net config");
292d1ef877fSJayaprakash Mutyala         rc = -1;
293d1ef877fSJayaprakash Mutyala         return rc;
294d1ef877fSJayaprakash Mutyala     }
295d1ef877fSJayaprakash Mutyala     std::copy(netConfInitialBytes,
296d1ef877fSJayaprakash Mutyala               netConfInitialBytes + sizeof(netConfInitialBytes),
297d1ef877fSJayaprakash Mutyala               configDataStartingAddress);
298d1ef877fSJayaprakash Mutyala 
299d1ef877fSJayaprakash Mutyala     if (payloadSize < skipFirstTwoBytes + addrSizeOffset + sizeof(addrSize))
300d1ef877fSJayaprakash Mutyala     {
30138108d9dSVernon Mauery         lg2::error("Invalid length of address size");
302d1ef877fSJayaprakash Mutyala         rc = -1;
303d1ef877fSJayaprakash Mutyala         return rc;
304d1ef877fSJayaprakash Mutyala     }
305d1ef877fSJayaprakash Mutyala     std::copy(&addrSize, &(addrSize) + sizeof(addrSize),
306d1ef877fSJayaprakash Mutyala               configDataStartingAddress + addrSizeOffset);
3076ec7daabSRatan Gupta 
308fd28dd7aSRatan Gupta #ifdef _IPMI_DEBUG_
309b51bf9c8SPatrick Venture     std::printf("\n===Printing the IPMI Formatted Data========\n");
310fd28dd7aSRatan Gupta 
311fd28dd7aSRatan Gupta     for (uint8_t pos = 0; pos < index; pos++)
312dcb10671SRatan Gupta     {
313d1ef877fSJayaprakash Mutyala         std::printf("%02x ", payloadStartingAddress[pos]);
314dcb10671SRatan Gupta     }
315fd28dd7aSRatan Gupta #endif
316fd28dd7aSRatan Gupta 
317fd28dd7aSRatan Gupta     return rc;
318fd28dd7aSRatan Gupta }
319fd28dd7aSRatan Gupta 
3206ec7daabSRatan Gupta /** @brief convert IPv4 and IPv6 addresses from binary to text form.
3216ec7daabSRatan Gupta  *  @param[in] family - IPv4/Ipv6
3226ec7daabSRatan Gupta  *  @param[in] data - req data pointer.
3236ec7daabSRatan Gupta  *  @param[in] offset - offset in the data.
3246ec7daabSRatan Gupta  *  @param[in] addrSize - size of the data which needs to be read from offset.
3256ec7daabSRatan Gupta  *  @returns address in text form.
3266ec7daabSRatan Gupta  */
3276ec7daabSRatan Gupta 
getAddrStr(uint8_t family,uint8_t * data,uint8_t offset,uint8_t addrSize)3280b02be92SPatrick Venture std::string getAddrStr(uint8_t family, uint8_t* data, uint8_t offset,
3290b02be92SPatrick Venture                        uint8_t addrSize)
3306ec7daabSRatan Gupta {
3316ec7daabSRatan Gupta     char ipAddr[INET6_ADDRSTRLEN] = {};
3326ec7daabSRatan Gupta 
3336ec7daabSRatan Gupta     switch (family)
3346ec7daabSRatan Gupta     {
3356ec7daabSRatan Gupta         case AF_INET:
3366ec7daabSRatan Gupta         {
33799db6885SPatrick Williams             struct sockaddr_in addr4{};
338b51bf9c8SPatrick Venture             std::memcpy(&addr4.sin_addr.s_addr, &data[offset], addrSize);
3396ec7daabSRatan Gupta 
3400b02be92SPatrick Venture             inet_ntop(AF_INET, &addr4.sin_addr, ipAddr, INET_ADDRSTRLEN);
3416ec7daabSRatan Gupta 
3426ec7daabSRatan Gupta             break;
3436ec7daabSRatan Gupta         }
3446ec7daabSRatan Gupta         case AF_INET6:
3456ec7daabSRatan Gupta         {
34699db6885SPatrick Williams             struct sockaddr_in6 addr6{};
347b51bf9c8SPatrick Venture             std::memcpy(&addr6.sin6_addr.s6_addr, &data[offset], addrSize);
3486ec7daabSRatan Gupta 
3490b02be92SPatrick Venture             inet_ntop(AF_INET6, &addr6.sin6_addr, ipAddr, INET6_ADDRSTRLEN);
3506ec7daabSRatan Gupta 
3516ec7daabSRatan Gupta             break;
3526ec7daabSRatan Gupta         }
3536ec7daabSRatan Gupta         default:
3546ec7daabSRatan Gupta         {
3556ec7daabSRatan Gupta             return {};
3566ec7daabSRatan Gupta         }
3576ec7daabSRatan Gupta     }
3586ec7daabSRatan Gupta 
3596ec7daabSRatan Gupta     return ipAddr;
3606ec7daabSRatan Gupta }
3616ec7daabSRatan Gupta 
setHostNetworkData(ipmi::message::Payload & data)362bfd8fc4bSjayaprakash Mutyala ipmi::Cc setHostNetworkData(ipmi::message::Payload& data)
363fd28dd7aSRatan Gupta {
364dcb10671SRatan Gupta     using namespace std::string_literals;
365bfd8fc4bSjayaprakash Mutyala     std::string hostNetworkConfig;
366bfd8fc4bSjayaprakash Mutyala     std::string mac("00:00:00:00:00:00");
3676ec7daabSRatan Gupta     std::string ipAddress, gateway;
368bfd8fc4bSjayaprakash Mutyala     std::string addrOrigin{0};
3696ec7daabSRatan Gupta     uint8_t addrSize{0};
370dcb10671SRatan Gupta     std::string addressOrigin =
3716ec7daabSRatan Gupta         "xyz.openbmc_project.Network.IP.AddressOrigin.DHCP";
3720b02be92SPatrick Venture     std::string addressType = "xyz.openbmc_project.Network.IP.Protocol.IPv4";
373dcb10671SRatan Gupta     uint8_t prefix{0};
3746ec7daabSRatan Gupta     uint8_t family = AF_INET;
375fd28dd7aSRatan Gupta 
376fd28dd7aSRatan Gupta     // cookie starts from second byte
377fd28dd7aSRatan Gupta     // version starts from sixth byte
378fd28dd7aSRatan Gupta 
379dcb10671SRatan Gupta     try
380dcb10671SRatan Gupta     {
381dcb10671SRatan Gupta         do
382dcb10671SRatan Gupta         {
383fd28dd7aSRatan Gupta             // cookie ==  0x21 0x70 0x62 0x21
384bfd8fc4bSjayaprakash Mutyala             data.trailingOk = true;
385bfd8fc4bSjayaprakash Mutyala             auto msgLen = data.size();
386bfd8fc4bSjayaprakash Mutyala             std::vector<uint8_t> msgPayloadBytes(msgLen);
387bfd8fc4bSjayaprakash Mutyala             if (data.unpack(msgPayloadBytes) != 0 || !data.fullyUnpacked())
388dcb10671SRatan Gupta             {
38938108d9dSVernon Mauery                 lg2::error("Error in unpacking message of setHostNetworkData");
390bfd8fc4bSjayaprakash Mutyala                 return ipmi::ccReqDataLenInvalid;
391bfd8fc4bSjayaprakash Mutyala             }
392bfd8fc4bSjayaprakash Mutyala 
393bfd8fc4bSjayaprakash Mutyala             uint8_t* msgPayloadStartingPos = msgPayloadBytes.data();
394bfd8fc4bSjayaprakash Mutyala             constexpr size_t cookieSize = 4;
395bfd8fc4bSjayaprakash Mutyala             if (msgLen < cookieOffset + cookieSize)
396bfd8fc4bSjayaprakash Mutyala             {
39738108d9dSVernon Mauery                 lg2::error("Error in cookie getting of setHostNetworkData");
398bfd8fc4bSjayaprakash Mutyala                 return ipmi::ccReqDataLenInvalid;
399bfd8fc4bSjayaprakash Mutyala             }
400bfd8fc4bSjayaprakash Mutyala             if (std::equal(msgPayloadStartingPos + cookieOffset,
401bfd8fc4bSjayaprakash Mutyala                            msgPayloadStartingPos + cookieOffset + cookieSize,
402bfd8fc4bSjayaprakash Mutyala                            (netConfInitialBytes + cookieOffset)) != 0)
403bfd8fc4bSjayaprakash Mutyala             {
404bfd8fc4bSjayaprakash Mutyala                 // all cookie == 0
405bfd8fc4bSjayaprakash Mutyala                 if (std::all_of(msgPayloadStartingPos + cookieOffset,
406bfd8fc4bSjayaprakash Mutyala                                 msgPayloadStartingPos + cookieOffset +
407bfd8fc4bSjayaprakash Mutyala                                     cookieSize,
408bfd8fc4bSjayaprakash Mutyala                                 [](int i) { return i == 0; }) == true)
409dcb10671SRatan Gupta                 {
410dcb10671SRatan Gupta                     // need to zero out the network settings.
411fd28dd7aSRatan Gupta                     break;
412fd28dd7aSRatan Gupta                 }
413dcb10671SRatan Gupta 
41438108d9dSVernon Mauery                 lg2::error("Invalid Cookie");
415dcb10671SRatan Gupta                 elog<InternalFailure>();
416fd28dd7aSRatan Gupta             }
417dcb10671SRatan Gupta 
418fd28dd7aSRatan Gupta             // vesion == 0x00 0x01
419bfd8fc4bSjayaprakash Mutyala             if (msgLen < versionOffset + sizeVersion)
420dcb10671SRatan Gupta             {
42138108d9dSVernon Mauery                 lg2::error("Error in version getting of setHostNetworkData");
422bfd8fc4bSjayaprakash Mutyala                 return ipmi::ccReqDataLenInvalid;
423bfd8fc4bSjayaprakash Mutyala             }
424bfd8fc4bSjayaprakash Mutyala             if (std::equal(msgPayloadStartingPos + versionOffset,
425bfd8fc4bSjayaprakash Mutyala                            msgPayloadStartingPos + versionOffset + sizeVersion,
426bfd8fc4bSjayaprakash Mutyala                            (netConfInitialBytes + versionOffset)) != 0)
427bfd8fc4bSjayaprakash Mutyala             {
42838108d9dSVernon Mauery                 lg2::error("Invalid Version");
429dcb10671SRatan Gupta                 elog<InternalFailure>();
430fd28dd7aSRatan Gupta             }
431fd28dd7aSRatan Gupta 
432bfd8fc4bSjayaprakash Mutyala             if (msgLen < macOffset + 6)
433bfd8fc4bSjayaprakash Mutyala             {
43438108d9dSVernon Mauery                 lg2::error(
435bfd8fc4bSjayaprakash Mutyala                     "Error in mac address getting of setHostNetworkData");
436bfd8fc4bSjayaprakash Mutyala                 return ipmi::ccReqDataLenInvalid;
437bfd8fc4bSjayaprakash Mutyala             }
438bfd8fc4bSjayaprakash Mutyala             std::stringstream result;
439bfd8fc4bSjayaprakash Mutyala             std::copy((msgPayloadStartingPos + macOffset),
440bfd8fc4bSjayaprakash Mutyala                       (msgPayloadStartingPos + macOffset + 5),
441bfd8fc4bSjayaprakash Mutyala                       std::ostream_iterator<int>(result, ":"));
442bfd8fc4bSjayaprakash Mutyala             mac = result.str();
443fd28dd7aSRatan Gupta 
444bfd8fc4bSjayaprakash Mutyala             if (msgLen < addrTypeOffset + sizeof(decltype(addrOrigin)))
445bfd8fc4bSjayaprakash Mutyala             {
44638108d9dSVernon Mauery                 lg2::error(
447bfd8fc4bSjayaprakash Mutyala                     "Error in original address getting of setHostNetworkData");
448bfd8fc4bSjayaprakash Mutyala                 return ipmi::ccReqDataLenInvalid;
449bfd8fc4bSjayaprakash Mutyala             }
450bfd8fc4bSjayaprakash Mutyala             std::copy(msgPayloadStartingPos + addrTypeOffset,
451bfd8fc4bSjayaprakash Mutyala                       msgPayloadStartingPos + addrTypeOffset +
452bfd8fc4bSjayaprakash Mutyala                           sizeof(decltype(addrOrigin)),
453bfd8fc4bSjayaprakash Mutyala                       std::ostream_iterator<int>(result, ""));
454bfd8fc4bSjayaprakash Mutyala             addrOrigin = result.str();
455fd28dd7aSRatan Gupta 
456bfd8fc4bSjayaprakash Mutyala             if (!addrOrigin.empty())
457dcb10671SRatan Gupta             {
458dcb10671SRatan Gupta                 addressOrigin =
4596ec7daabSRatan Gupta                     "xyz.openbmc_project.Network.IP.AddressOrigin.Static";
460fd28dd7aSRatan Gupta             }
461fd28dd7aSRatan Gupta 
462bfd8fc4bSjayaprakash Mutyala             if (msgLen < addrSizeOffset + sizeof(decltype(addrSize)))
463bfd8fc4bSjayaprakash Mutyala             {
46438108d9dSVernon Mauery                 lg2::error(
465bfd8fc4bSjayaprakash Mutyala                     "Error in address size getting of setHostNetworkData");
466bfd8fc4bSjayaprakash Mutyala                 return ipmi::ccReqDataLenInvalid;
467bfd8fc4bSjayaprakash Mutyala             }
4686ec7daabSRatan Gupta             // Get the address size
469bfd8fc4bSjayaprakash Mutyala             std::copy(msgPayloadStartingPos + addrSizeOffset,
470bfd8fc4bSjayaprakash Mutyala                       (msgPayloadStartingPos + addrSizeOffset +
471bfd8fc4bSjayaprakash Mutyala                        sizeof(decltype(addrSize))),
472bfd8fc4bSjayaprakash Mutyala                       &addrSize);
473fd28dd7aSRatan Gupta 
474bfd8fc4bSjayaprakash Mutyala             uint8_t prefixOffset = ipAddrOffset + addrSize;
475bfd8fc4bSjayaprakash Mutyala             if (msgLen < prefixOffset + sizeof(decltype(prefix)))
476bfd8fc4bSjayaprakash Mutyala             {
47738108d9dSVernon Mauery                 lg2::error("Error in prefix getting of setHostNetworkData");
478bfd8fc4bSjayaprakash Mutyala                 return ipmi::ccReqDataLenInvalid;
479bfd8fc4bSjayaprakash Mutyala             }
4804c521025SWilliam A. Kennington III             // std::copy(msgPayloadStartingPos + prefixOffset,
4814c521025SWilliam A. Kennington III             //           msgPayloadStartingPos + prefixOffset +
4824c521025SWilliam A. Kennington III             //               sizeof(decltype(prefix)),
4834c521025SWilliam A. Kennington III             //           &prefix);
4844c521025SWilliam A. Kennington III             // Workaround compiler misdetecting out of bounds memcpy
4854c521025SWilliam A. Kennington III             prefix = msgPayloadStartingPos[prefixOffset];
486fd28dd7aSRatan Gupta 
4876ec7daabSRatan Gupta             uint8_t gatewayOffset = prefixOffset + sizeof(decltype(prefix));
4888c31d237SRatan Gupta             if (addrSize != ipmi::network::IPV4_ADDRESS_SIZE_BYTE)
4896ec7daabSRatan Gupta             {
4906ec7daabSRatan Gupta                 addressType = "xyz.openbmc_project.Network.IP.Protocol.IPv6";
4916ec7daabSRatan Gupta                 family = AF_INET6;
4926ec7daabSRatan Gupta             }
4936ec7daabSRatan Gupta 
494bfd8fc4bSjayaprakash Mutyala             if (msgLen < ipAddrOffset + addrSize)
495bfd8fc4bSjayaprakash Mutyala             {
49638108d9dSVernon Mauery                 lg2::error("Error in IP address getting of setHostNetworkData");
497bfd8fc4bSjayaprakash Mutyala                 return ipmi::ccReqDataLenInvalid;
498bfd8fc4bSjayaprakash Mutyala             }
499bfd8fc4bSjayaprakash Mutyala             ipAddress = getAddrStr(family, msgPayloadStartingPos, ipAddrOffset,
500bfd8fc4bSjayaprakash Mutyala                                    addrSize);
501d70f4534SRatan Gupta 
502bfd8fc4bSjayaprakash Mutyala             if (msgLen < gatewayOffset + addrSize)
503bfd8fc4bSjayaprakash Mutyala             {
50438108d9dSVernon Mauery                 lg2::error(
505bfd8fc4bSjayaprakash Mutyala                     "Error in gateway address getting of setHostNetworkData");
506bfd8fc4bSjayaprakash Mutyala                 return ipmi::ccReqDataLenInvalid;
507bfd8fc4bSjayaprakash Mutyala             }
508bfd8fc4bSjayaprakash Mutyala             gateway = getAddrStr(family, msgPayloadStartingPos, gatewayOffset,
509bfd8fc4bSjayaprakash Mutyala                                  addrSize);
5106ec7daabSRatan Gupta 
511fd28dd7aSRatan Gupta         } while (0);
512fd28dd7aSRatan Gupta 
513fd28dd7aSRatan Gupta         // Cookie == 0 or it is a valid cookie
5141318a5edSPatrick Williams         hostNetworkConfig +=
5151318a5edSPatrick Williams             "ipaddress="s + ipAddress + ",prefix="s + std::to_string(prefix) +
5161318a5edSPatrick Williams             ",gateway="s + gateway + ",mac="s + mac + ",addressOrigin="s +
5170b02be92SPatrick Venture             addressOrigin;
518fd28dd7aSRatan Gupta 
5195d82f474SPatrick Williams         sdbusplus::bus_t bus(ipmid_get_sd_bus_connection());
52001d4bd1aSRatan Gupta 
52101d4bd1aSRatan Gupta         auto ipObjectInfo = ipmi::getDbusObject(bus, IP_INTERFACE,
52201d4bd1aSRatan Gupta                                                 SETTINGS_ROOT, SETTINGS_MATCH);
52301d4bd1aSRatan Gupta         auto macObjectInfo = ipmi::getDbusObject(bus, MAC_INTERFACE,
52401d4bd1aSRatan Gupta                                                  SETTINGS_ROOT, SETTINGS_MATCH);
525dcb10671SRatan Gupta         // set the dbus property
52601d4bd1aSRatan Gupta         ipmi::setDbusProperty(bus, ipObjectInfo.second, ipObjectInfo.first,
527dcb10671SRatan Gupta                               IP_INTERFACE, "Address", std::string(ipAddress));
52801d4bd1aSRatan Gupta         ipmi::setDbusProperty(bus, ipObjectInfo.second, ipObjectInfo.first,
529dcb10671SRatan Gupta                               IP_INTERFACE, "PrefixLength", prefix);
53001d4bd1aSRatan Gupta         ipmi::setDbusProperty(bus, ipObjectInfo.second, ipObjectInfo.first,
531dcb10671SRatan Gupta                               IP_INTERFACE, "Origin", addressOrigin);
53201d4bd1aSRatan Gupta         ipmi::setDbusProperty(bus, ipObjectInfo.second, ipObjectInfo.first,
533dcb10671SRatan Gupta                               IP_INTERFACE, "Gateway", std::string(gateway));
5340b02be92SPatrick Venture         ipmi::setDbusProperty(
5350b02be92SPatrick Venture             bus, ipObjectInfo.second, ipObjectInfo.first, IP_INTERFACE, "Type",
536dcb10671SRatan Gupta             std::string("xyz.openbmc_project.Network.IP.Protocol.IPv4"));
53701d4bd1aSRatan Gupta         ipmi::setDbusProperty(bus, macObjectInfo.second, macObjectInfo.first,
538dcb10671SRatan Gupta                               MAC_INTERFACE, "MACAddress", std::string(mac));
539fd28dd7aSRatan Gupta 
54038108d9dSVernon Mauery         lg2::debug("Network configuration changed: {NETWORKCONFIG}",
54138108d9dSVernon Mauery                    "NETWORKCONFIG", hostNetworkConfig);
542fd28dd7aSRatan Gupta     }
543a2ad2da8SPatrick Williams     catch (const sdbusplus::exception_t& e)
544dcb10671SRatan Gupta     {
545dcb10671SRatan Gupta         commit<InternalFailure>();
54638108d9dSVernon Mauery         lg2::error("Error in ipmiChassisSetSysBootOptions call");
547bfd8fc4bSjayaprakash Mutyala         return ipmi::ccUnspecifiedError;
548dcb10671SRatan Gupta     }
549dcb10671SRatan Gupta 
550bfd8fc4bSjayaprakash Mutyala     return ipmi::ccSuccess;
551fd28dd7aSRatan Gupta }
552fd28dd7aSRatan Gupta 
getPOHCounter()553a59d83f8SNagaraju Goruganti uint32_t getPOHCounter()
554a59d83f8SNagaraju Goruganti {
5555d82f474SPatrick Williams     sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
556a59d83f8SNagaraju Goruganti 
5571318a5edSPatrick Williams     auto chassisStateObj =
5581318a5edSPatrick Williams         ipmi::getDbusObject(bus, chassisPOHStateIntf, chassisStateRoot, match);
559a59d83f8SNagaraju Goruganti 
5601318a5edSPatrick Williams     auto service =
5611318a5edSPatrick Williams         ipmi::getService(bus, chassisPOHStateIntf, chassisStateObj.first);
562a59d83f8SNagaraju Goruganti 
5631318a5edSPatrick Williams     auto propValue =
5641318a5edSPatrick Williams         ipmi::getDbusProperty(bus, service, chassisStateObj.first,
5651318a5edSPatrick Williams                               chassisPOHStateIntf, pohCounterProperty);
566a59d83f8SNagaraju Goruganti 
567f442e119SVernon Mauery     return std::get<uint32_t>(propValue);
568a59d83f8SNagaraju Goruganti }
569a59d83f8SNagaraju Goruganti 
57043263c60Sanil kumar appana /** @brief Implements the get chassis capabilities command
57143263c60Sanil kumar appana  *
57243263c60Sanil kumar appana  *  @returns IPMI completion code plus response data
57343263c60Sanil kumar appana  *  chassisCapFlags        - chassis capability flag
57443263c60Sanil kumar appana  *  chassisFRUInfoDevAddr  - chassis FRU info Device Address
57543263c60Sanil kumar appana  *  chassisSDRDevAddr      - chassis SDR device address
57643263c60Sanil kumar appana  *  chassisSELDevAddr      - chassis SEL device address
57743263c60Sanil kumar appana  *  chassisSMDevAddr       - chassis system management device address
57843263c60Sanil kumar appana  *  chassisBridgeDevAddr   - chassis bridge device address
57943263c60Sanil kumar appana  */
58086d8bd79SKarthick Sundarrajan ipmi::RspType<bool,    // chassis intrusion sensor
58186d8bd79SKarthick Sundarrajan               bool,    // chassis Front panel lockout
58286d8bd79SKarthick Sundarrajan               bool,    // chassis NMI
58386d8bd79SKarthick Sundarrajan               bool,    // chassis power interlock
58486d8bd79SKarthick Sundarrajan               uint4_t, // reserved
58543263c60Sanil kumar appana               uint8_t, // chassis FRU info Device Address
58643263c60Sanil kumar appana               uint8_t, // chassis SDR device address
58743263c60Sanil kumar appana               uint8_t, // chassis SEL device address
58843263c60Sanil kumar appana               uint8_t, // chassis system management device address
58943263c60Sanil kumar appana               uint8_t  // chassis bridge device address
59043263c60Sanil kumar appana               >
ipmiGetChassisCap()59143263c60Sanil kumar appana     ipmiGetChassisCap()
5928d15fb49SNan Li {
59343263c60Sanil kumar appana     ipmi::PropertyMap properties;
594ae4b040bSYong Li     try
595ae4b040bSYong Li     {
5965d82f474SPatrick Williams         sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
597ae4b040bSYong Li 
598ae4b040bSYong Li         ipmi::DbusObjectInfo chassisCapObject =
599ae4b040bSYong Li             ipmi::getDbusObject(bus, chassisCapIntf);
6008d15fb49SNan Li 
6018d15fb49SNan Li         // capabilities flags
6028d15fb49SNan Li         // [7..4] - reserved
6038d15fb49SNan Li         // [3] – 1b = provides power interlock  (IPM 1.5)
6048d15fb49SNan Li         // [2] – 1b = provides Diagnostic Interrupt (FP NMI)
605ae4b040bSYong Li         // [1] – 1b = provides “Front Panel Lockout” (indicates that the chassis
606ae4b040bSYong Li         // has capabilities
607ae4b040bSYong Li         //            to lock out external power control and reset button or
608ae4b040bSYong Li         //            front panel interfaces and/or detect tampering with those
6090b02be92SPatrick Venture         //            interfaces).
6108d15fb49SNan Li         // [0] -1b = Chassis provides intrusion (physical security) sensor.
6118d15fb49SNan Li         // set to default value 0x0.
6128d15fb49SNan Li 
6131318a5edSPatrick Williams         properties =
6141318a5edSPatrick Williams             ipmi::getAllDbusProperties(bus, chassisCapObject.second,
6151318a5edSPatrick Williams                                        chassisCapObject.first, chassisCapIntf);
616ae4b040bSYong Li     }
617a2ad2da8SPatrick Williams     catch (const std::exception& e)
618ae4b040bSYong Li     {
61938108d9dSVernon Mauery         lg2::error("Failed to fetch Chassis Capability properties: {ERROR}",
62038108d9dSVernon Mauery                    "ERROR", e);
62143263c60Sanil kumar appana         return ipmi::responseUnspecifiedError();
622ae4b040bSYong Li     }
6238d15fb49SNan Li 
62486d8bd79SKarthick Sundarrajan     bool* chassisIntrusionFlag =
62586d8bd79SKarthick Sundarrajan         std::get_if<bool>(&properties[chassisIntrusionProp]);
62686d8bd79SKarthick Sundarrajan     if (chassisIntrusionFlag == nullptr)
62743263c60Sanil kumar appana     {
62838108d9dSVernon Mauery         lg2::error("Error to get chassis Intrusion flags");
62986d8bd79SKarthick Sundarrajan         return ipmi::responseUnspecifiedError();
63086d8bd79SKarthick Sundarrajan     }
63186d8bd79SKarthick Sundarrajan     bool* chassisFrontPanelFlag =
63286d8bd79SKarthick Sundarrajan         std::get_if<bool>(&properties[chassisFrontPanelLockoutProp]);
63386d8bd79SKarthick Sundarrajan     if (chassisFrontPanelFlag == nullptr)
63486d8bd79SKarthick Sundarrajan     {
63538108d9dSVernon Mauery         lg2::error("Error to get chassis intrusion flags");
63686d8bd79SKarthick Sundarrajan         return ipmi::responseUnspecifiedError();
63786d8bd79SKarthick Sundarrajan     }
63886d8bd79SKarthick Sundarrajan     bool* chassisNMIFlag = std::get_if<bool>(&properties[chassisNMIProp]);
63986d8bd79SKarthick Sundarrajan     if (chassisNMIFlag == nullptr)
64086d8bd79SKarthick Sundarrajan     {
64138108d9dSVernon Mauery         lg2::error("Error to get chassis NMI flags");
64286d8bd79SKarthick Sundarrajan         return ipmi::responseUnspecifiedError();
64386d8bd79SKarthick Sundarrajan     }
64486d8bd79SKarthick Sundarrajan     bool* chassisPowerInterlockFlag =
64586d8bd79SKarthick Sundarrajan         std::get_if<bool>(&properties[chassisPowerInterlockProp]);
64686d8bd79SKarthick Sundarrajan     if (chassisPowerInterlockFlag == nullptr)
64786d8bd79SKarthick Sundarrajan     {
64838108d9dSVernon Mauery         lg2::error("Error to get chassis power interlock flags");
64943263c60Sanil kumar appana         return ipmi::responseUnspecifiedError();
65043263c60Sanil kumar appana     }
65143263c60Sanil kumar appana     uint8_t* chassisFRUInfoDevAddr =
65243263c60Sanil kumar appana         std::get_if<uint8_t>(&properties[chassisFRUDevAddrProp]);
65343263c60Sanil kumar appana     if (chassisFRUInfoDevAddr == nullptr)
65443263c60Sanil kumar appana     {
65538108d9dSVernon Mauery         lg2::error("Error to get chassis FRU info device address");
65643263c60Sanil kumar appana         return ipmi::responseUnspecifiedError();
65743263c60Sanil kumar appana     }
65843263c60Sanil kumar appana     uint8_t* chassisSDRDevAddr =
65943263c60Sanil kumar appana         std::get_if<uint8_t>(&properties[chassisSDRDevAddrProp]);
66043263c60Sanil kumar appana     if (chassisSDRDevAddr == nullptr)
66143263c60Sanil kumar appana     {
66238108d9dSVernon Mauery         lg2::error("Error to get chassis SDR device address");
66343263c60Sanil kumar appana         return ipmi::responseUnspecifiedError();
66443263c60Sanil kumar appana     }
66543263c60Sanil kumar appana     uint8_t* chassisSELDevAddr =
66643263c60Sanil kumar appana         std::get_if<uint8_t>(&properties[chassisSELDevAddrProp]);
66743263c60Sanil kumar appana     if (chassisSELDevAddr == nullptr)
66843263c60Sanil kumar appana     {
66938108d9dSVernon Mauery         lg2::error("Error to get chassis SEL device address");
67043263c60Sanil kumar appana         return ipmi::responseUnspecifiedError();
67143263c60Sanil kumar appana     }
67243263c60Sanil kumar appana     uint8_t* chassisSMDevAddr =
67343263c60Sanil kumar appana         std::get_if<uint8_t>(&properties[chassisSMDevAddrProp]);
67443263c60Sanil kumar appana     if (chassisSMDevAddr == nullptr)
67543263c60Sanil kumar appana     {
67638108d9dSVernon Mauery         lg2::error("Error to get chassis SM device address");
67743263c60Sanil kumar appana         return ipmi::responseUnspecifiedError();
67843263c60Sanil kumar appana     }
67943263c60Sanil kumar appana     uint8_t* chassisBridgeDevAddr =
68043263c60Sanil kumar appana         std::get_if<uint8_t>(&properties[chassisBridgeDevAddrProp]);
68143263c60Sanil kumar appana     if (chassisBridgeDevAddr == nullptr)
68243263c60Sanil kumar appana     {
68338108d9dSVernon Mauery         lg2::error("Error to get chassis bridge device address");
68443263c60Sanil kumar appana         return ipmi::responseUnspecifiedError();
68543263c60Sanil kumar appana     }
68643263c60Sanil kumar appana 
6871318a5edSPatrick Williams     return ipmi::responseSuccess(
6881318a5edSPatrick Williams         *chassisIntrusionFlag, *chassisFrontPanelFlag, *chassisNMIFlag,
6891318a5edSPatrick Williams         *chassisPowerInterlockFlag, 0, *chassisFRUInfoDevAddr,
6901318a5edSPatrick Williams         *chassisSDRDevAddr, *chassisSELDevAddr, *chassisSMDevAddr,
69186d8bd79SKarthick Sundarrajan         *chassisBridgeDevAddr);
692ae4b040bSYong Li }
693ae4b040bSYong Li 
694894d0220Sanil kumar appana /** @brief implements set chassis capalibities command
695894d0220Sanil kumar appana  *  @param intrusion        - chassis intrusion
696894d0220Sanil kumar appana  *  @param fpLockout        - frontpannel lockout
697894d0220Sanil kumar appana  *  @param reserved1        - skip one bit
698894d0220Sanil kumar appana  *  @param fruDeviceAddr    - chassis FRU info Device Address
699894d0220Sanil kumar appana  *  @param sdrDeviceAddr    - chassis SDR device address
700894d0220Sanil kumar appana  *  @param selDeviceAddr    - chassis SEL device address
701894d0220Sanil kumar appana  *  @param smDeviceAddr     - chassis system management device address
702894d0220Sanil kumar appana  *  @param bridgeDeviceAddr - chassis bridge device address
703894d0220Sanil kumar appana  *
704894d0220Sanil kumar appana  *  @returns IPMI completion code
705894d0220Sanil kumar appana  */
ipmiSetChassisCap(bool intrusion,bool fpLockout,uint6_t reserved1,uint8_t fruDeviceAddr,uint8_t sdrDeviceAddr,uint8_t selDeviceAddr,uint8_t smDeviceAddr,uint8_t bridgeDeviceAddr)7061318a5edSPatrick Williams ipmi::RspType<> ipmiSetChassisCap(
7071318a5edSPatrick Williams     bool intrusion, bool fpLockout, uint6_t reserved1,
708894d0220Sanil kumar appana 
709894d0220Sanil kumar appana     uint8_t fruDeviceAddr,
710894d0220Sanil kumar appana 
711894d0220Sanil kumar appana     uint8_t sdrDeviceAddr,
712894d0220Sanil kumar appana 
713894d0220Sanil kumar appana     uint8_t selDeviceAddr,
714894d0220Sanil kumar appana 
715894d0220Sanil kumar appana     uint8_t smDeviceAddr,
716894d0220Sanil kumar appana 
717894d0220Sanil kumar appana     uint8_t bridgeDeviceAddr)
718ae4b040bSYong Li {
719ae4b040bSYong Li     // check input data
720894d0220Sanil kumar appana     if (reserved1 != 0)
721ae4b040bSYong Li     {
72238108d9dSVernon Mauery         lg2::error("Unsupported request parameter");
723894d0220Sanil kumar appana         return ipmi::responseInvalidFieldRequest();
724ae4b040bSYong Li     }
725ae4b040bSYong Li 
726894d0220Sanil kumar appana     if ((fruDeviceAddr & ~chassisCapAddrMask) != 0)
727ae4b040bSYong Li     {
72838108d9dSVernon Mauery         lg2::error("Unsupported request parameter(FRU Addr) for REQ={REQ}",
72938108d9dSVernon Mauery                    "REQ", lg2::hex, fruDeviceAddr);
730894d0220Sanil kumar appana         return ipmi::responseInvalidFieldRequest();
731ae4b040bSYong Li     }
732894d0220Sanil kumar appana     if ((sdrDeviceAddr & ~chassisCapAddrMask) != 0)
733ae4b040bSYong Li     {
73438108d9dSVernon Mauery         lg2::error("Unsupported request parameter(SDR Addr) for REQ={REQ}",
73538108d9dSVernon Mauery                    "REQ", lg2::hex, sdrDeviceAddr);
736894d0220Sanil kumar appana         return ipmi::responseInvalidFieldRequest();
737ae4b040bSYong Li     }
738ae4b040bSYong Li 
739894d0220Sanil kumar appana     if ((selDeviceAddr & ~chassisCapAddrMask) != 0)
740ae4b040bSYong Li     {
74138108d9dSVernon Mauery         lg2::error("Unsupported request parameter(SEL Addr) for REQ={REQ}",
74238108d9dSVernon Mauery                    "REQ", lg2::hex, selDeviceAddr);
743894d0220Sanil kumar appana         return ipmi::responseInvalidFieldRequest();
744ae4b040bSYong Li     }
745ae4b040bSYong Li 
746894d0220Sanil kumar appana     if ((smDeviceAddr & ~chassisCapAddrMask) != 0)
747ae4b040bSYong Li     {
74838108d9dSVernon Mauery         lg2::error("Unsupported request parameter(SM Addr) for REQ={REQ}",
74938108d9dSVernon Mauery                    "REQ", lg2::hex, smDeviceAddr);
750894d0220Sanil kumar appana         return ipmi::responseInvalidFieldRequest();
751ae4b040bSYong Li     }
752ae4b040bSYong Li 
753894d0220Sanil kumar appana     if ((bridgeDeviceAddr & ~chassisCapAddrMask) != 0)
754ae4b040bSYong Li     {
75538108d9dSVernon Mauery         lg2::error("Unsupported request parameter(Bridge Addr) for REQ={REQ}",
75638108d9dSVernon Mauery                    "REQ", lg2::hex, bridgeDeviceAddr);
757894d0220Sanil kumar appana         return ipmi::responseInvalidFieldRequest();
758ae4b040bSYong Li     }
759ae4b040bSYong Li 
760ae4b040bSYong Li     try
761ae4b040bSYong Li     {
7625d82f474SPatrick Williams         sdbusplus::bus_t bus(ipmid_get_sd_bus_connection());
763ae4b040bSYong Li         ipmi::DbusObjectInfo chassisCapObject =
764ae4b040bSYong Li             ipmi::getDbusObject(bus, chassisCapIntf);
765ae4b040bSYong Li 
766ae4b040bSYong Li         ipmi::setDbusProperty(bus, chassisCapObject.second,
767ae4b040bSYong Li                               chassisCapObject.first, chassisCapIntf,
76886d8bd79SKarthick Sundarrajan                               chassisIntrusionProp, intrusion);
76986d8bd79SKarthick Sundarrajan 
77086d8bd79SKarthick Sundarrajan         ipmi::setDbusProperty(bus, chassisCapObject.second,
77186d8bd79SKarthick Sundarrajan                               chassisCapObject.first, chassisCapIntf,
77286d8bd79SKarthick Sundarrajan                               chassisFrontPanelLockoutProp, fpLockout);
773ae4b040bSYong Li 
774ae4b040bSYong Li         ipmi::setDbusProperty(bus, chassisCapObject.second,
775ae4b040bSYong Li                               chassisCapObject.first, chassisCapIntf,
776894d0220Sanil kumar appana                               chassisFRUDevAddrProp, fruDeviceAddr);
777ae4b040bSYong Li 
778ae4b040bSYong Li         ipmi::setDbusProperty(bus, chassisCapObject.second,
779ae4b040bSYong Li                               chassisCapObject.first, chassisCapIntf,
780894d0220Sanil kumar appana                               chassisSDRDevAddrProp, sdrDeviceAddr);
781ae4b040bSYong Li 
782ae4b040bSYong Li         ipmi::setDbusProperty(bus, chassisCapObject.second,
783ae4b040bSYong Li                               chassisCapObject.first, chassisCapIntf,
784894d0220Sanil kumar appana                               chassisSELDevAddrProp, selDeviceAddr);
785ae4b040bSYong Li 
786ae4b040bSYong Li         ipmi::setDbusProperty(bus, chassisCapObject.second,
787ae4b040bSYong Li                               chassisCapObject.first, chassisCapIntf,
788894d0220Sanil kumar appana                               chassisSMDevAddrProp, smDeviceAddr);
789ae4b040bSYong Li 
790ae4b040bSYong Li         ipmi::setDbusProperty(bus, chassisCapObject.second,
791ae4b040bSYong Li                               chassisCapObject.first, chassisCapIntf,
792894d0220Sanil kumar appana                               chassisBridgeDevAddrProp, bridgeDeviceAddr);
793ae4b040bSYong Li     }
794a2ad2da8SPatrick Williams     catch (const std::exception& e)
795ae4b040bSYong Li     {
79638108d9dSVernon Mauery         lg2::error("Failed to set chassis capability properties: {ERR}", "ERR",
79738108d9dSVernon Mauery                    e);
798894d0220Sanil kumar appana         return ipmi::responseUnspecifiedError();
799ae4b040bSYong Li     }
800894d0220Sanil kumar appana     return ipmi::responseSuccess();
8018d15fb49SNan Li }
8028d15fb49SNan Li 
803b12b0c01SVishwanatha Subbanna //------------------------------------------
804b12b0c01SVishwanatha Subbanna // Calls into Host State Manager Dbus object
805b12b0c01SVishwanatha Subbanna //------------------------------------------
initiateHostStateTransition(ipmi::Context::ptr & ctx,State::Host::Transition transition)806664e1c31SJason M. Bills int initiateHostStateTransition(ipmi::Context::ptr& ctx,
807664e1c31SJason M. Bills                                 State::Host::Transition transition)
80898a23840SMatthew Barth {
809b12b0c01SVishwanatha Subbanna     // OpenBMC Host State Manager dbus framework
810664e1c31SJason M. Bills     constexpr auto hostStatePath = "/xyz/openbmc_project/state/host0";
811664e1c31SJason M. Bills     constexpr auto hostStateIntf = "xyz.openbmc_project.State.Host";
812b12b0c01SVishwanatha Subbanna 
813b12b0c01SVishwanatha Subbanna     // Convert to string equivalent of the passed in transition enum.
814523e2d1bSWilly Tu     auto request =
815523e2d1bSWilly Tu         sdbusplus::common::xyz::openbmc_project::state::convertForMessage(
816523e2d1bSWilly Tu             transition);
817b12b0c01SVishwanatha Subbanna 
818664e1c31SJason M. Bills     std::string service;
8191318a5edSPatrick Williams     boost::system::error_code ec =
8201318a5edSPatrick Williams         ipmi::getService(ctx, hostStateIntf, hostStatePath, service);
821664e1c31SJason M. Bills 
822664e1c31SJason M. Bills     if (!ec)
823664e1c31SJason M. Bills     {
824664e1c31SJason M. Bills         ec = ipmi::setDbusProperty(ctx, service, hostStatePath, hostStateIntf,
825664e1c31SJason M. Bills                                    "RequestedHostTransition", request);
826664e1c31SJason M. Bills     }
827664e1c31SJason M. Bills     if (ec)
82898a23840SMatthew Barth     {
82938108d9dSVernon Mauery         lg2::error(
83038108d9dSVernon Mauery             "Failed to initiate transition for request {REQUEST}: {EXCEPTION}",
83138108d9dSVernon Mauery             "REQUEST", request, "EXCEPTION", ec.message());
832664e1c31SJason M. Bills         return -1;
83398a23840SMatthew Barth     }
83438108d9dSVernon Mauery     lg2::info(
83538108d9dSVernon Mauery         "Transition request {REQUEST} initiated successfully by user {USERID}",
83638108d9dSVernon Mauery         "REQUEST", request, "USERID", ctx->userId);
837664e1c31SJason M. Bills     return 0;
83898a23840SMatthew Barth }
83998a23840SMatthew Barth 
8406b0ceaa4SKuiying Wang //------------------------------------------
841ad588bf5SJason M. Bills // Calls into Chassis State Manager Dbus object
842ad588bf5SJason M. Bills //------------------------------------------
initiateChassisStateTransition(ipmi::Context::ptr & ctx,State::Chassis::Transition transition)843ad588bf5SJason M. Bills int initiateChassisStateTransition(ipmi::Context::ptr& ctx,
844ad588bf5SJason M. Bills                                    State::Chassis::Transition transition)
845ad588bf5SJason M. Bills {
846ad588bf5SJason M. Bills     // OpenBMC Chassis State Manager dbus framework
847ad588bf5SJason M. Bills     constexpr auto chassisStatePath = "/xyz/openbmc_project/state/chassis0";
848ad588bf5SJason M. Bills     constexpr auto chassisStateIntf = "xyz.openbmc_project.State.Chassis";
849ad588bf5SJason M. Bills 
850ad588bf5SJason M. Bills     std::string service;
8511318a5edSPatrick Williams     boost::system::error_code ec =
8521318a5edSPatrick Williams         ipmi::getService(ctx, chassisStateIntf, chassisStatePath, service);
853ad588bf5SJason M. Bills 
854ad588bf5SJason M. Bills     // Convert to string equivalent of the passed in transition enum.
855523e2d1bSWilly Tu     auto request =
856523e2d1bSWilly Tu         sdbusplus::common::xyz::openbmc_project::state::convertForMessage(
857523e2d1bSWilly Tu             transition);
858ad588bf5SJason M. Bills 
859ad588bf5SJason M. Bills     if (!ec)
860ad588bf5SJason M. Bills     {
861ad588bf5SJason M. Bills         ec = ipmi::setDbusProperty(ctx, service, chassisStatePath,
862ad588bf5SJason M. Bills                                    chassisStateIntf, "RequestedPowerTransition",
863ad588bf5SJason M. Bills                                    request);
864ad588bf5SJason M. Bills     }
865ad588bf5SJason M. Bills     if (ec)
866ad588bf5SJason M. Bills     {
86738108d9dSVernon Mauery         lg2::error("Failed to initiate transition {REQUEST}: {EXCEPTION}",
86838108d9dSVernon Mauery                    "REQUEST", request, "EXCEPTION", ec.message());
86938108d9dSVernon Mauery 
870ad588bf5SJason M. Bills         return -1;
871ad588bf5SJason M. Bills     }
872ad588bf5SJason M. Bills 
873ad588bf5SJason M. Bills     return 0;
874ad588bf5SJason M. Bills }
875ad588bf5SJason M. Bills 
876ad588bf5SJason M. Bills //------------------------------------------
877337a0978SZev Weiss // Trigger an NMI on the host via dbus
8786b0ceaa4SKuiying Wang //------------------------------------------
doNmi(ipmi::Context::ptr & ctx)879337a0978SZev Weiss static int doNmi(ipmi::Context::ptr& ctx)
8806b0ceaa4SKuiying Wang {
881337a0978SZev Weiss     constexpr const char* nmiIntfName = "xyz.openbmc_project.Control.Host.NMI";
882337a0978SZev Weiss     ipmi::DbusObjectInfo nmiObj{};
883337a0978SZev Weiss     boost::system::error_code ec;
8846b0ceaa4SKuiying Wang 
885337a0978SZev Weiss     ec = ipmi::getDbusObject(ctx, nmiIntfName, nmiObj);
8869bb4a386SVernon Mauery     if (ec)
8876b0ceaa4SKuiying Wang     {
88838108d9dSVernon Mauery         lg2::error("Failed to find NMI service: {ERROR}", "ERROR",
88938108d9dSVernon Mauery                    ec.message());
890337a0978SZev Weiss         return -1;
891337a0978SZev Weiss     }
892337a0978SZev Weiss 
893337a0978SZev Weiss     ctx->bus->yield_method_call<void>(ctx->yield, ec, nmiObj.second,
894337a0978SZev Weiss                                       nmiObj.first, nmiIntfName, "NMI");
895337a0978SZev Weiss     if (ec)
896337a0978SZev Weiss     {
89738108d9dSVernon Mauery         lg2::error("NMI call failed: {ERROR}", "ERROR", ec.message());
898337a0978SZev Weiss         elog<InternalFailure>();
8996b0ceaa4SKuiying Wang         return -1;
9006b0ceaa4SKuiying Wang     }
9016b0ceaa4SKuiying Wang 
9026b0ceaa4SKuiying Wang     return 0;
9036b0ceaa4SKuiying Wang }
9046b0ceaa4SKuiying Wang 
90518b70d11SDeepak Kodihalli namespace power_policy
906fca6a4fcSAndrew Geissler {
907fdd8ec55SNan Li 
908523e2d1bSWilly Tu using namespace sdbusplus::server::xyz::openbmc_project::control::power;
90918b70d11SDeepak Kodihalli using IpmiValue = uint8_t;
91018b70d11SDeepak Kodihalli using DbusValue = RestorePolicy::Policy;
911fdd8ec55SNan Li 
9124a8a4eb9SVernon Mauery const std::map<DbusValue, IpmiValue> dbusToIpmi = {
91318b70d11SDeepak Kodihalli     {RestorePolicy::Policy::AlwaysOff, 0x00},
91418b70d11SDeepak Kodihalli     {RestorePolicy::Policy::Restore, 0x01},
915e561d3eaSGeorge Liu     {RestorePolicy::Policy::AlwaysOn, 0x02},
916e561d3eaSGeorge Liu     {RestorePolicy::Policy::None, 0x03}};
917fdd8ec55SNan Li 
918c6713cffSYong Li static constexpr uint8_t noChange = 0x03;
919c6713cffSYong Li static constexpr uint8_t allSupport = 0x01 | 0x02 | 0x04;
9204a8a4eb9SVernon Mauery 
9214a8a4eb9SVernon Mauery /* helper function for Get Chassis Status Command
9224a8a4eb9SVernon Mauery  */
getPowerRestorePolicy()9234a8a4eb9SVernon Mauery std::optional<uint2_t> getPowerRestorePolicy()
9244a8a4eb9SVernon Mauery {
9254a8a4eb9SVernon Mauery     uint2_t restorePolicy = 0;
9264a8a4eb9SVernon Mauery     using namespace chassis::internal;
9274a8a4eb9SVernon Mauery 
928225dec85SJames Feist     settings::Objects& objects = cache::getObjects();
929225dec85SJames Feist 
9304a8a4eb9SVernon Mauery     try
9314a8a4eb9SVernon Mauery     {
9324a8a4eb9SVernon Mauery         const auto& powerRestoreSetting =
933225dec85SJames Feist             objects.map.at(powerRestoreIntf).front();
9344a8a4eb9SVernon Mauery         ipmi::Value result = ipmi::getDbusProperty(
9354a8a4eb9SVernon Mauery             *getSdBus(),
936225dec85SJames Feist             objects.service(powerRestoreSetting, powerRestoreIntf).c_str(),
9374a8a4eb9SVernon Mauery             powerRestoreSetting.c_str(), powerRestoreIntf,
9384a8a4eb9SVernon Mauery             "PowerRestorePolicy");
9394a8a4eb9SVernon Mauery         auto powerRestore = RestorePolicy::convertPolicyFromString(
9404a8a4eb9SVernon Mauery             std::get<std::string>(result));
9414a8a4eb9SVernon Mauery         restorePolicy = dbusToIpmi.at(powerRestore);
9424a8a4eb9SVernon Mauery     }
9434a8a4eb9SVernon Mauery     catch (const std::exception& e)
9444a8a4eb9SVernon Mauery     {
94538108d9dSVernon Mauery         lg2::error(
94638108d9dSVernon Mauery             "Failed to fetch pgood property ({PATH}/{INTERFACE}): {ERROR}",
94738108d9dSVernon Mauery             "PATH", objects.map.at(powerRestoreIntf).front(), "INTERFACE",
94838108d9dSVernon Mauery             powerRestoreIntf, "ERROR", e);
949225dec85SJames Feist         cache::objectsPtr.reset();
9504a8a4eb9SVernon Mauery         return std::nullopt;
9514a8a4eb9SVernon Mauery     }
9524a8a4eb9SVernon Mauery     return std::make_optional(restorePolicy);
9534a8a4eb9SVernon Mauery }
9544a8a4eb9SVernon Mauery 
9554a8a4eb9SVernon Mauery /*
9564a8a4eb9SVernon Mauery  * getPowerStatus
9574a8a4eb9SVernon Mauery  * helper function for Get Chassis Status Command
9584a8a4eb9SVernon Mauery  * return - optional value for pgood (no value on error)
9594a8a4eb9SVernon Mauery  */
getPowerStatus()9604a8a4eb9SVernon Mauery std::optional<bool> getPowerStatus()
9614a8a4eb9SVernon Mauery {
9624a8a4eb9SVernon Mauery     bool powerGood = false;
9634a8a4eb9SVernon Mauery     std::shared_ptr<sdbusplus::asio::connection> busp = getSdBus();
9644a8a4eb9SVernon Mauery     try
9654a8a4eb9SVernon Mauery     {
9663de424cdSJason M. Bills         constexpr const char* chassisStatePath =
9673de424cdSJason M. Bills             "/xyz/openbmc_project/state/chassis0";
9683de424cdSJason M. Bills         constexpr const char* chassisStateIntf =
9693de424cdSJason M. Bills             "xyz.openbmc_project.State.Chassis";
9701318a5edSPatrick Williams         auto service =
9711318a5edSPatrick Williams             ipmi::getService(*busp, chassisStateIntf, chassisStatePath);
9724a8a4eb9SVernon Mauery 
9733de424cdSJason M. Bills         ipmi::Value powerState =
9743de424cdSJason M. Bills             ipmi::getDbusProperty(*busp, service, chassisStatePath,
9753de424cdSJason M. Bills                                   chassisStateIntf, "CurrentPowerState");
976ee3983b0SChau Ly         std::string powerStateStr = std::get<std::string>(powerState);
977ee3983b0SChau Ly         if (powerStateStr.ends_with(".On") ||
978ee3983b0SChau Ly             powerStateStr.ends_with(".TransitioningToOff"))
979ee3983b0SChau Ly         {
980ee3983b0SChau Ly             powerGood = true;
981ee3983b0SChau Ly         }
9824a8a4eb9SVernon Mauery     }
9834a8a4eb9SVernon Mauery     catch (const std::exception& e)
9844a8a4eb9SVernon Mauery     {
9854a8a4eb9SVernon Mauery         try
9864a8a4eb9SVernon Mauery         {
9874a8a4eb9SVernon Mauery             // FIXME: some legacy modules use the older path; try that next
9884a8a4eb9SVernon Mauery             constexpr const char* legacyPwrCtrlObj =
9894a8a4eb9SVernon Mauery                 "/org/openbmc/control/power0";
9904a8a4eb9SVernon Mauery             constexpr const char* legacyPwrCtrlIntf =
9914a8a4eb9SVernon Mauery                 "org.openbmc.control.Power";
9921318a5edSPatrick Williams             auto service =
9931318a5edSPatrick Williams                 ipmi::getService(*busp, legacyPwrCtrlIntf, legacyPwrCtrlObj);
9944a8a4eb9SVernon Mauery 
9954a8a4eb9SVernon Mauery             ipmi::Value variant = ipmi::getDbusProperty(
9964a8a4eb9SVernon Mauery                 *busp, service, legacyPwrCtrlObj, legacyPwrCtrlIntf, "pgood");
9974a8a4eb9SVernon Mauery             powerGood = static_cast<bool>(std::get<int>(variant));
9984a8a4eb9SVernon Mauery         }
9994a8a4eb9SVernon Mauery         catch (const std::exception& e)
10004a8a4eb9SVernon Mauery         {
100138108d9dSVernon Mauery             lg2::error("Failed to fetch pgood property: {ERROR}", "ERROR", e);
10024a8a4eb9SVernon Mauery             return std::nullopt;
10034a8a4eb9SVernon Mauery         }
10044a8a4eb9SVernon Mauery     }
10054a8a4eb9SVernon Mauery     return std::make_optional(powerGood);
10064a8a4eb9SVernon Mauery }
10074a8a4eb9SVernon Mauery 
100870ce7357SYong Li /*
100970ce7357SYong Li  * getACFailStatus
101070ce7357SYong Li  * helper function for Get Chassis Status Command
101170ce7357SYong Li  * return - bool value for ACFail (false on error)
101270ce7357SYong Li  */
getACFailStatus()101370ce7357SYong Li bool getACFailStatus()
101470ce7357SYong Li {
101570ce7357SYong Li     constexpr const char* powerControlObj =
101670ce7357SYong Li         "/xyz/openbmc_project/Chassis/Control/Power0";
101770ce7357SYong Li     constexpr const char* powerControlIntf =
101870ce7357SYong Li         "xyz.openbmc_project.Chassis.Control.Power";
101970ce7357SYong Li     bool acFail = false;
102070ce7357SYong Li     std::shared_ptr<sdbusplus::asio::connection> bus = getSdBus();
102170ce7357SYong Li     try
102270ce7357SYong Li     {
10231318a5edSPatrick Williams         auto service =
10241318a5edSPatrick Williams             ipmi::getService(*bus, powerControlIntf, powerControlObj);
102570ce7357SYong Li 
102670ce7357SYong Li         ipmi::Value variant = ipmi::getDbusProperty(
102770ce7357SYong Li             *bus, service, powerControlObj, powerControlIntf, "PFail");
102870ce7357SYong Li         acFail = std::get<bool>(variant);
102970ce7357SYong Li     }
103070ce7357SYong Li     catch (const std::exception& e)
103170ce7357SYong Li     {
103238108d9dSVernon Mauery         lg2::error(
103337de2e1aSKonstantin Aladyshev             "Failed to fetch PFail property ({PATH}/{INTERFACE}): {ERROR}",
103438108d9dSVernon Mauery             "PATH", powerControlObj, "INTERFACE", powerControlIntf, "ERROR", e);
103570ce7357SYong Li     }
103670ce7357SYong Li     return acFail;
103770ce7357SYong Li }
103818b70d11SDeepak Kodihalli } // namespace power_policy
1039fdd8ec55SNan Li 
getButtonEnabled(const std::string & buttonPath,const std::string & buttonIntf)10404a8a4eb9SVernon Mauery static std::optional<bool> getButtonEnabled(const std::string& buttonPath,
10414a8a4eb9SVernon Mauery                                             const std::string& buttonIntf)
10424a8a4eb9SVernon Mauery {
10434a8a4eb9SVernon Mauery     std::shared_ptr<sdbusplus::asio::connection> busp = getSdBus();
10444a8a4eb9SVernon Mauery     bool buttonDisabled = false;
10454a8a4eb9SVernon Mauery     try
10464a8a4eb9SVernon Mauery     {
10474a8a4eb9SVernon Mauery         auto service = ipmi::getService(*busp, buttonIntf, buttonPath);
10484a8a4eb9SVernon Mauery         ipmi::Value enabled = ipmi::getDbusProperty(*busp, service, buttonPath,
10494a8a4eb9SVernon Mauery                                                     buttonIntf, "Enabled");
10504a8a4eb9SVernon Mauery         buttonDisabled = !std::get<bool>(enabled);
10514a8a4eb9SVernon Mauery     }
10525d82f474SPatrick Williams     catch (const sdbusplus::exception_t& e)
10534a8a4eb9SVernon Mauery     {
105438108d9dSVernon Mauery         lg2::error("Fail to get button Enabled property ({PATH}): {ERROR}",
105538108d9dSVernon Mauery                    "PATH", buttonPath, "ERROR", e);
10564a8a4eb9SVernon Mauery         return std::nullopt;
10574a8a4eb9SVernon Mauery     }
10584a8a4eb9SVernon Mauery     return std::make_optional(buttonDisabled);
10594a8a4eb9SVernon Mauery }
10604a8a4eb9SVernon Mauery 
setButtonEnabled(ipmi::Context::ptr & ctx,const std::string & buttonPath,const std::string & buttonIntf,bool enable)106121addc57SKuiying Wang static bool setButtonEnabled(ipmi::Context::ptr& ctx,
106221addc57SKuiying Wang                              const std::string& buttonPath,
106321addc57SKuiying Wang                              const std::string& buttonIntf, bool enable)
106421addc57SKuiying Wang {
106521addc57SKuiying Wang     std::string service;
106621addc57SKuiying Wang     boost::system::error_code ec;
106721addc57SKuiying Wang     ec = ipmi::getService(ctx, buttonIntf, buttonPath, service);
106821addc57SKuiying Wang     if (!ec)
106921addc57SKuiying Wang     {
107021addc57SKuiying Wang         ec = ipmi::setDbusProperty(ctx, service, buttonPath, buttonIntf,
107121addc57SKuiying Wang                                    "Enabled", enable);
107221addc57SKuiying Wang     }
107321addc57SKuiying Wang     if (ec)
107421addc57SKuiying Wang     {
107538108d9dSVernon Mauery         lg2::error(
107638108d9dSVernon Mauery             "Fail to set button Enabled property ({SERVICE}:{PATH}): {ERROR}",
107738108d9dSVernon Mauery             "SERVICE", service, "PATH", buttonPath, "ERROR", ec.message());
107821addc57SKuiying Wang         return false;
107921addc57SKuiying Wang     }
108021addc57SKuiying Wang     return true;
108121addc57SKuiying Wang }
108221addc57SKuiying Wang 
getChassisIntrusionStatus(ipmi::Context::ptr & ctx)10839e666cdaSChau Ly static std::optional<bool> getChassisIntrusionStatus(ipmi::Context::ptr& ctx)
10849e666cdaSChau Ly {
1085*8c1376caSChau Ly     std::vector<std::string> interfaces = {std::string(Intrusion::interface)};
1086*8c1376caSChau Ly     ipmi::ObjectTree objs;
1087*8c1376caSChau Ly     std::string propVal;
1088*8c1376caSChau Ly     std::optional<bool> ret = std::nullopt;
10899e666cdaSChau Ly 
1090*8c1376caSChau Ly     boost::system::error_code ec =
1091*8c1376caSChau Ly         ipmi::getSubTree(ctx, interfaces, std::string("/"), 0, objs);
1092*8c1376caSChau Ly 
1093*8c1376caSChau Ly     if (ec)
10949e666cdaSChau Ly     {
1095*8c1376caSChau Ly         lg2::error("Fail to find Chassis Intrusion Interface on D-Bus "
1096*8c1376caSChau Ly                    "({INTERFACE}): {ERROR}",
1097*8c1376caSChau Ly                    "INTERFACE", Intrusion::interface, "ERROR", ec.message());
1098*8c1376caSChau Ly         return ret;
1099*8c1376caSChau Ly     }
1100*8c1376caSChau Ly 
1101*8c1376caSChau Ly     for (const auto& [path, map] : objs)
1102*8c1376caSChau Ly     {
1103*8c1376caSChau Ly         for (const auto& [service, intfs] : map)
1104*8c1376caSChau Ly         {
11059e666cdaSChau Ly             ec = ipmi::getDbusProperty<std::string>(
1106*8c1376caSChau Ly                 ctx, service, path, Intrusion::interface, "Status", propVal);
1107*8c1376caSChau Ly             if (ec)
11089e666cdaSChau Ly             {
110938108d9dSVernon Mauery                 lg2::error("Fail to get Chassis Intrusion Status property "
1110*8c1376caSChau Ly                            "({SERVICE}/{PATH}/{INTERFACE}): {ERROR}",
1111*8c1376caSChau Ly                            "SERVICE", service, "PATH", path, "INTERFACE",
1112*8c1376caSChau Ly                            Intrusion::interface, "ERROR", ec.message());
1113*8c1376caSChau Ly             }
1114*8c1376caSChau Ly             else
1115*8c1376caSChau Ly             {
1116*8c1376caSChau Ly                 // return false if all values are Normal
1117*8c1376caSChau Ly                 // return true if one value is not Normal
1118*8c1376caSChau Ly                 // return nullopt when no value can be retrieved from D-Bus
1119*8c1376caSChau Ly                 auto status =
1120*8c1376caSChau Ly                     sdbusplus::message::convert_from_string<Intrusion::Status>(
1121*8c1376caSChau Ly                         propVal)
1122*8c1376caSChau Ly                         .value();
1123*8c1376caSChau Ly                 if (status == Intrusion::Status::Normal)
1124*8c1376caSChau Ly                 {
1125*8c1376caSChau Ly                     ret = std::make_optional(false);
1126*8c1376caSChau Ly                 }
1127*8c1376caSChau Ly                 else
1128*8c1376caSChau Ly                 {
1129*8c1376caSChau Ly                     ret = std::make_optional(true);
1130*8c1376caSChau Ly                     return ret;
1131*8c1376caSChau Ly                 }
1132*8c1376caSChau Ly             }
1133*8c1376caSChau Ly         }
1134*8c1376caSChau Ly     }
1135*8c1376caSChau Ly     return ret;
11369e666cdaSChau Ly }
11379e666cdaSChau Ly 
1138fdd8ec55SNan Li //----------------------------------------------------------------------
1139fdd8ec55SNan Li // Get Chassis Status commands
1140fdd8ec55SNan Li //----------------------------------------------------------------------
11414a8a4eb9SVernon Mauery ipmi::RspType<bool,    // Power is on
11424a8a4eb9SVernon Mauery               bool,    // Power overload
11434a8a4eb9SVernon Mauery               bool,    // Interlock
11444a8a4eb9SVernon Mauery               bool,    // power fault
11454a8a4eb9SVernon Mauery               bool,    // power control fault
11464a8a4eb9SVernon Mauery               uint2_t, // power restore policy
11474a8a4eb9SVernon Mauery               bool,    // reserved
11484a8a4eb9SVernon Mauery 
11494a8a4eb9SVernon Mauery               bool,    // AC failed
11504a8a4eb9SVernon Mauery               bool,    // last power down caused by a Power overload
11514a8a4eb9SVernon Mauery               bool,    // last power down caused by a power interlock
11524a8a4eb9SVernon Mauery               bool,    // last power down caused by power fault
11534a8a4eb9SVernon Mauery               bool,    // last ‘Power is on’ state was entered via IPMI command
11544a8a4eb9SVernon Mauery               uint3_t, // reserved
11554a8a4eb9SVernon Mauery 
11564a8a4eb9SVernon Mauery               bool,    // Chassis intrusion active
11574a8a4eb9SVernon Mauery               bool,    // Front Panel Lockout active
11584a8a4eb9SVernon Mauery               bool,    // Drive Fault
11594a8a4eb9SVernon Mauery               bool,    // Cooling/fan fault detected
11604a8a4eb9SVernon Mauery               uint2_t, // Chassis Identify State
11614a8a4eb9SVernon Mauery               bool,    // Chassis Identify command and state info supported
11624a8a4eb9SVernon Mauery               bool,    // reserved
11634a8a4eb9SVernon Mauery 
11644a8a4eb9SVernon Mauery               bool,    // Power off button disabled
11654a8a4eb9SVernon Mauery               bool,    // Reset button disabled
11664a8a4eb9SVernon Mauery               bool,    // Diagnostic Interrupt button disabled
11674a8a4eb9SVernon Mauery               bool,    // Standby (sleep) button disabled
11684a8a4eb9SVernon Mauery               bool,    // Power off button disable allowed
11694a8a4eb9SVernon Mauery               bool,    // Reset button disable allowed
11704a8a4eb9SVernon Mauery               bool,    // Diagnostic Interrupt button disable allowed
11714a8a4eb9SVernon Mauery               bool     // Standby (sleep) button disable allowed
11724a8a4eb9SVernon Mauery               >
ipmiGetChassisStatus(ipmi::Context::ptr & ctx)11739e666cdaSChau Ly     ipmiGetChassisStatus(ipmi::Context::ptr& ctx)
1174fdd8ec55SNan Li {
117518b70d11SDeepak Kodihalli     using namespace chassis::internal;
11764a8a4eb9SVernon Mauery     std::optional<uint2_t> restorePolicy =
11774a8a4eb9SVernon Mauery         power_policy::getPowerRestorePolicy();
11784a8a4eb9SVernon Mauery     std::optional<bool> powerGood = power_policy::getPowerStatus();
11794a8a4eb9SVernon Mauery     if (!restorePolicy || !powerGood)
118018b70d11SDeepak Kodihalli     {
11814a8a4eb9SVernon Mauery         return ipmi::responseUnspecifiedError();
118218b70d11SDeepak Kodihalli     }
1183fdd8ec55SNan Li 
1184fdd8ec55SNan Li     //  Front Panel Button Capabilities and disable/enable status(Optional)
11851318a5edSPatrick Williams     std::optional<bool> powerButtonReading =
11861318a5edSPatrick Williams         getButtonEnabled(powerButtonPath, powerButtonIntf);
11876d5b2f7eSVernon Mauery     // allow disable if the interface is present
11886d5b2f7eSVernon Mauery     bool powerButtonDisableAllow = static_cast<bool>(powerButtonReading);
11896d5b2f7eSVernon Mauery     // default return the button is enabled (not disabled)
11906d5b2f7eSVernon Mauery     bool powerButtonDisabled = false;
11916d5b2f7eSVernon Mauery     if (powerButtonDisableAllow)
11924a8a4eb9SVernon Mauery     {
11936d5b2f7eSVernon Mauery         // return the real value of the button status, if present
11946d5b2f7eSVernon Mauery         powerButtonDisabled = *powerButtonReading;
11956d5b2f7eSVernon Mauery     }
11966d5b2f7eSVernon Mauery 
11971318a5edSPatrick Williams     std::optional<bool> resetButtonReading =
11981318a5edSPatrick Williams         getButtonEnabled(resetButtonPath, resetButtonIntf);
11996d5b2f7eSVernon Mauery     // allow disable if the interface is present
12006d5b2f7eSVernon Mauery     bool resetButtonDisableAllow = static_cast<bool>(resetButtonReading);
12016d5b2f7eSVernon Mauery     // default return the button is enabled (not disabled)
12026d5b2f7eSVernon Mauery     bool resetButtonDisabled = false;
12036d5b2f7eSVernon Mauery     if (resetButtonDisableAllow)
12046d5b2f7eSVernon Mauery     {
12056d5b2f7eSVernon Mauery         // return the real value of the button status, if present
12066d5b2f7eSVernon Mauery         resetButtonDisabled = *resetButtonReading;
12074a8a4eb9SVernon Mauery     }
1208fdd8ec55SNan Li 
120970ce7357SYong Li     bool powerDownAcFailed = power_policy::getACFailStatus();
121070ce7357SYong Li 
12119e666cdaSChau Ly     bool chassisIntrusionActive = false;
12129e666cdaSChau Ly     std::optional<bool> chassisIntrusionStatus = getChassisIntrusionStatus(ctx);
12139e666cdaSChau Ly     if (chassisIntrusionStatus)
12149e666cdaSChau Ly     {
12159e666cdaSChau Ly         chassisIntrusionActive = chassisIntrusionStatus.value();
12169e666cdaSChau Ly     }
12179e666cdaSChau Ly 
12184a8a4eb9SVernon Mauery     // This response has a lot of hard-coded, unsupported fields
12194a8a4eb9SVernon Mauery     // They are set to false or 0
12204a8a4eb9SVernon Mauery     constexpr bool powerOverload = false;
12214a8a4eb9SVernon Mauery     constexpr bool chassisInterlock = false;
12224a8a4eb9SVernon Mauery     constexpr bool powerFault = false;
12234a8a4eb9SVernon Mauery     constexpr bool powerControlFault = false;
12244a8a4eb9SVernon Mauery     constexpr bool powerDownOverload = false;
12254a8a4eb9SVernon Mauery     constexpr bool powerDownInterlock = false;
12264a8a4eb9SVernon Mauery     constexpr bool powerDownPowerFault = false;
12274a8a4eb9SVernon Mauery     constexpr bool powerStatusIPMI = false;
12284a8a4eb9SVernon Mauery     constexpr bool frontPanelLockoutActive = false;
12294a8a4eb9SVernon Mauery     constexpr bool driveFault = false;
12304a8a4eb9SVernon Mauery     constexpr bool coolingFanFault = false;
12314a8a4eb9SVernon Mauery     // chassisIdentifySupport set because this command is implemented
12324a8a4eb9SVernon Mauery     constexpr bool chassisIdentifySupport = true;
12337a0e5dfcSWilliam A. Kennington III     uint2_t chassisIdentifyState = types::enum_cast<uint2_t>(chassisIDState);
12344a8a4eb9SVernon Mauery     constexpr bool diagButtonDisabled = false;
12354a8a4eb9SVernon Mauery     constexpr bool sleepButtonDisabled = false;
12364a8a4eb9SVernon Mauery     constexpr bool diagButtonDisableAllow = false;
12374a8a4eb9SVernon Mauery     constexpr bool sleepButtonDisableAllow = false;
12384a8a4eb9SVernon Mauery 
12394a8a4eb9SVernon Mauery     return ipmi::responseSuccess(
12404a8a4eb9SVernon Mauery         *powerGood, powerOverload, chassisInterlock, powerFault,
12414a8a4eb9SVernon Mauery         powerControlFault, *restorePolicy,
12424a8a4eb9SVernon Mauery         false, // reserved
12434a8a4eb9SVernon Mauery 
12444a8a4eb9SVernon Mauery         powerDownAcFailed, powerDownOverload, powerDownInterlock,
12454a8a4eb9SVernon Mauery         powerDownPowerFault, powerStatusIPMI,
12464a8a4eb9SVernon Mauery         uint3_t(0), // reserved
12474a8a4eb9SVernon Mauery 
12484a8a4eb9SVernon Mauery         chassisIntrusionActive, frontPanelLockoutActive, driveFault,
12494a8a4eb9SVernon Mauery         coolingFanFault, chassisIdentifyState, chassisIdentifySupport,
12504a8a4eb9SVernon Mauery         false, // reserved
12514a8a4eb9SVernon Mauery 
12526d5b2f7eSVernon Mauery         powerButtonDisabled, resetButtonDisabled, diagButtonDisabled,
12534a8a4eb9SVernon Mauery         sleepButtonDisabled, powerButtonDisableAllow, resetButtonDisableAllow,
12544a8a4eb9SVernon Mauery         diagButtonDisableAllow, sleepButtonDisableAllow);
1255fdd8ec55SNan Li }
125698a23840SMatthew Barth 
1257074f64d4SVijay Khemka enum class IpmiRestartCause
1258074f64d4SVijay Khemka {
1259074f64d4SVijay Khemka     Unknown = 0x0,
1260074f64d4SVijay Khemka     RemoteCommand = 0x1,
1261074f64d4SVijay Khemka     ResetButton = 0x2,
1262074f64d4SVijay Khemka     PowerButton = 0x3,
1263074f64d4SVijay Khemka     WatchdogTimer = 0x4,
1264074f64d4SVijay Khemka     PowerPolicyAlwaysOn = 0x6,
1265074f64d4SVijay Khemka     PowerPolicyPreviousState = 0x7,
1266074f64d4SVijay Khemka     SoftReset = 0xa,
1267074f64d4SVijay Khemka };
1268074f64d4SVijay Khemka 
restartCauseToIpmiRestartCause(State::Host::RestartCause cause)126969b4c281SPatrick Williams static IpmiRestartCause restartCauseToIpmiRestartCause(
127069b4c281SPatrick Williams     State::Host::RestartCause cause)
1271074f64d4SVijay Khemka {
1272074f64d4SVijay Khemka     switch (cause)
1273074f64d4SVijay Khemka     {
1274074f64d4SVijay Khemka         case State::Host::RestartCause::Unknown:
1275074f64d4SVijay Khemka         {
1276074f64d4SVijay Khemka             return IpmiRestartCause::Unknown;
1277074f64d4SVijay Khemka         }
1278074f64d4SVijay Khemka         case State::Host::RestartCause::RemoteCommand:
1279074f64d4SVijay Khemka         {
1280074f64d4SVijay Khemka             return IpmiRestartCause::RemoteCommand;
1281074f64d4SVijay Khemka         }
1282074f64d4SVijay Khemka         case State::Host::RestartCause::ResetButton:
1283074f64d4SVijay Khemka         {
1284074f64d4SVijay Khemka             return IpmiRestartCause::ResetButton;
1285074f64d4SVijay Khemka         }
1286074f64d4SVijay Khemka         case State::Host::RestartCause::PowerButton:
1287074f64d4SVijay Khemka         {
1288074f64d4SVijay Khemka             return IpmiRestartCause::PowerButton;
1289074f64d4SVijay Khemka         }
1290074f64d4SVijay Khemka         case State::Host::RestartCause::WatchdogTimer:
1291074f64d4SVijay Khemka         {
1292074f64d4SVijay Khemka             return IpmiRestartCause::WatchdogTimer;
1293074f64d4SVijay Khemka         }
1294074f64d4SVijay Khemka         case State::Host::RestartCause::PowerPolicyAlwaysOn:
1295074f64d4SVijay Khemka         {
1296074f64d4SVijay Khemka             return IpmiRestartCause::PowerPolicyAlwaysOn;
1297074f64d4SVijay Khemka         }
1298074f64d4SVijay Khemka         case State::Host::RestartCause::PowerPolicyPreviousState:
1299074f64d4SVijay Khemka         {
1300074f64d4SVijay Khemka             return IpmiRestartCause::PowerPolicyPreviousState;
1301074f64d4SVijay Khemka         }
1302074f64d4SVijay Khemka         case State::Host::RestartCause::SoftReset:
1303074f64d4SVijay Khemka         {
1304074f64d4SVijay Khemka             return IpmiRestartCause::SoftReset;
1305074f64d4SVijay Khemka         }
1306074f64d4SVijay Khemka         default:
1307074f64d4SVijay Khemka         {
1308074f64d4SVijay Khemka             return IpmiRestartCause::Unknown;
1309074f64d4SVijay Khemka         }
1310074f64d4SVijay Khemka     }
1311074f64d4SVijay Khemka }
1312074f64d4SVijay Khemka 
1313074f64d4SVijay Khemka /*
1314074f64d4SVijay Khemka  * getRestartCause
1315074f64d4SVijay Khemka  * helper function for Get Host restart cause Command
1316074f64d4SVijay Khemka  * return - optional value for RestartCause (no value on error)
1317074f64d4SVijay Khemka  */
getRestartCause(ipmi::Context::ptr ctx)1318074f64d4SVijay Khemka static std::optional<uint4_t> getRestartCause(ipmi::Context::ptr ctx)
1319074f64d4SVijay Khemka {
1320ced0ddf1Sokashany     constexpr const char* restartCausePath = "/xyz/openbmc_project/state/host0";
1321ced0ddf1Sokashany     constexpr const char* restartCauseIntf = "xyz.openbmc_project.State.Host";
1322074f64d4SVijay Khemka 
1323074f64d4SVijay Khemka     std::string service;
13241318a5edSPatrick Williams     boost::system::error_code ec =
13251318a5edSPatrick Williams         ipmi::getService(ctx, restartCauseIntf, restartCausePath, service);
1326074f64d4SVijay Khemka     if (!ec)
1327074f64d4SVijay Khemka     {
1328074f64d4SVijay Khemka         std::string restartCauseStr;
1329074f64d4SVijay Khemka         ec = ipmi::getDbusProperty<std::string>(
1330074f64d4SVijay Khemka             ctx, service, restartCausePath, restartCauseIntf, "RestartCause",
1331074f64d4SVijay Khemka             restartCauseStr);
1332074f64d4SVijay Khemka         if (!ec)
1333074f64d4SVijay Khemka         {
1334074f64d4SVijay Khemka             auto cause =
1335074f64d4SVijay Khemka                 State::Host::convertRestartCauseFromString(restartCauseStr);
13367a0e5dfcSWilliam A. Kennington III             return types::enum_cast<uint4_t>(
13377a0e5dfcSWilliam A. Kennington III                 restartCauseToIpmiRestartCause(cause));
1338074f64d4SVijay Khemka         }
1339074f64d4SVijay Khemka     }
1340074f64d4SVijay Khemka 
134138108d9dSVernon Mauery     lg2::error(
134238108d9dSVernon Mauery         "Failed to fetch RestartCause property ({PATH}/{INTERFACE}): {ERROR}",
134338108d9dSVernon Mauery         "ERROR", ec.message(), "PATH", restartCausePath, "INTERFACE",
134438108d9dSVernon Mauery         restartCauseIntf);
1345074f64d4SVijay Khemka     return std::nullopt;
1346074f64d4SVijay Khemka }
1347074f64d4SVijay Khemka 
1348074f64d4SVijay Khemka ipmi::RspType<uint4_t, // Restart Cause
1349074f64d4SVijay Khemka               uint4_t, // reserved
1350074f64d4SVijay Khemka               uint8_t  // channel number (not supported)
1351074f64d4SVijay Khemka               >
ipmiGetSystemRestartCause(ipmi::Context::ptr ctx)1352074f64d4SVijay Khemka     ipmiGetSystemRestartCause(ipmi::Context::ptr ctx)
1353074f64d4SVijay Khemka {
1354074f64d4SVijay Khemka     std::optional<uint4_t> cause = getRestartCause(ctx);
1355074f64d4SVijay Khemka     if (!cause)
1356074f64d4SVijay Khemka     {
1357074f64d4SVijay Khemka         return ipmi::responseUnspecifiedError();
1358074f64d4SVijay Khemka     }
1359074f64d4SVijay Khemka 
1360916d4232SVernon Mauery     constexpr uint4_t reserved = 0;
1361916d4232SVernon Mauery     auto channel = static_cast<uint8_t>(ctx->channel);
1362916d4232SVernon Mauery     return ipmi::responseSuccess(cause.value(), reserved, channel);
1363074f64d4SVijay Khemka }
1364dafff5f4Sanil kumar appana /** @brief Implementation of chassis control command
1365dafff5f4Sanil kumar appana  *
1366dafff5f4Sanil kumar appana  *  @param - chassisControl command byte
1367dafff5f4Sanil kumar appana  *
1368dafff5f4Sanil kumar appana  *  @return  Success or InvalidFieldRequest.
1369dafff5f4Sanil kumar appana  */
ipmiChassisControl(ipmi::Context::ptr & ctx,uint8_t chassisControl)1370664e1c31SJason M. Bills ipmi::RspType<> ipmiChassisControl(ipmi::Context::ptr& ctx,
1371664e1c31SJason M. Bills                                    uint8_t chassisControl)
137298a23840SMatthew Barth {
137398a23840SMatthew Barth     int rc = 0;
1374dafff5f4Sanil kumar appana     switch (chassisControl)
137598a23840SMatthew Barth     {
1376a66239bbSVishwanatha Subbanna         case CMD_POWER_ON:
1377664e1c31SJason M. Bills             rc = initiateHostStateTransition(ctx, State::Host::Transition::On);
1378a66239bbSVishwanatha Subbanna             break;
137998a23840SMatthew Barth         case CMD_POWER_OFF:
1380c2c3a40aSJason M. Bills             rc = initiateChassisStateTransition(
1381c2c3a40aSJason M. Bills                 ctx, State::Chassis::Transition::Off);
138298a23840SMatthew Barth             break;
138398a23840SMatthew Barth         case CMD_HARD_RESET:
1384664e1c31SJason M. Bills             rc = initiateHostStateTransition(
1385664e1c31SJason M. Bills                 ctx, State::Host::Transition::ForceWarmReboot);
1386d0a7fcd5SChanh Nguyen             break;
1387bb5190e2SVishwanatha Subbanna         case CMD_POWER_CYCLE:
1388664e1c31SJason M. Bills             rc = initiateHostStateTransition(ctx,
1389664e1c31SJason M. Bills                                              State::Host::Transition::Reboot);
139098a23840SMatthew Barth             break;
13918b26d353SVishwanatha Subbanna         case CMD_SOFT_OFF_VIA_OVER_TEMP:
1392664e1c31SJason M. Bills             rc = initiateHostStateTransition(ctx, State::Host::Transition::Off);
13938b26d353SVishwanatha Subbanna             break;
13946b0ceaa4SKuiying Wang         case CMD_PULSE_DIAGNOSTIC_INTR:
1395337a0978SZev Weiss             rc = doNmi(ctx);
13966b0ceaa4SKuiying Wang             break;
13976b0ceaa4SKuiying Wang 
139898a23840SMatthew Barth         default:
139998a23840SMatthew Barth         {
140038108d9dSVernon Mauery             lg2::error("Invalid Chassis Control command: {CMD}", "CMD",
140138108d9dSVernon Mauery                        lg2::hex, chassisControl);
1402dafff5f4Sanil kumar appana             return ipmi::responseInvalidFieldRequest();
140398a23840SMatthew Barth         }
140498a23840SMatthew Barth     }
140598a23840SMatthew Barth 
1406dafff5f4Sanil kumar appana     return ((rc < 0) ? ipmi::responseUnspecifiedError()
1407dafff5f4Sanil kumar appana                      : ipmi::responseSuccess());
140898a23840SMatthew Barth }
140998a23840SMatthew Barth 
14106706c1ccSMarri Devender Rao /** @brief Return D-Bus connection string to enclosure identify LED object
14116706c1ccSMarri Devender Rao  *
14126706c1ccSMarri Devender Rao  *  @param[in, out] connection - connection to D-Bus object
14136706c1ccSMarri Devender Rao  *  @return a IPMI return code
14146706c1ccSMarri Devender Rao  */
getEnclosureIdentifyConnection()14156706c1ccSMarri Devender Rao std::string getEnclosureIdentifyConnection()
14165110c125STom Joseph {
14175110c125STom Joseph     // lookup enclosure_identify group owner(s) in mapper
14183e3cc35bSGeorge Liu     try
14195110c125STom Joseph     {
14203e3cc35bSGeorge Liu         return ipmi::getService(*getSdBus(), "xyz.openbmc_project.Led.Group",
14213e3cc35bSGeorge Liu                                 identify_led_object_name);
14223e3cc35bSGeorge Liu     }
14233e3cc35bSGeorge Liu     catch (const std::exception& e)
14243e3cc35bSGeorge Liu     {
142538108d9dSVernon Mauery         lg2::error("Chassis Identify: Error communicating to mapper: {ERROR}",
142638108d9dSVernon Mauery                    "ERROR", e);
14276706c1ccSMarri Devender Rao         elog<InternalFailure>();
14285110c125STom Joseph     }
14296706c1ccSMarri Devender Rao }
14305110c125STom Joseph 
14316706c1ccSMarri Devender Rao /** @brief Turn On/Off enclosure identify LED
14326706c1ccSMarri Devender Rao  *
14336706c1ccSMarri Devender Rao  *  @param[in] flag - true to turn on LED, false to turn off
14346706c1ccSMarri Devender Rao  *  @return a IPMI return code
14356706c1ccSMarri Devender Rao  */
enclosureIdentifyLed(bool flag)14366706c1ccSMarri Devender Rao void enclosureIdentifyLed(bool flag)
14375110c125STom Joseph {
14386706c1ccSMarri Devender Rao     using namespace chassis::internal;
14393e3cc35bSGeorge Liu     try
14403e3cc35bSGeorge Liu     {
144169c945eaSPatrick Williams         std::string connection = getEnclosureIdentifyConnection();
14423e3cc35bSGeorge Liu 
1443400cc789SVernon Mauery         auto msg = std::string("enclosureIdentifyLed(") +
1444400cc789SVernon Mauery                    boost::lexical_cast<std::string>(flag) + ")";
144538108d9dSVernon Mauery         lg2::debug(msg.c_str());
14463e3cc35bSGeorge Liu 
14473e3cc35bSGeorge Liu         ipmi::setDbusProperty(*getSdBus(), connection, identify_led_object_name,
14483e3cc35bSGeorge Liu                               "xyz.openbmc_project.Led.Group", "Asserted",
14493e3cc35bSGeorge Liu                               flag);
14503e3cc35bSGeorge Liu     }
14513e3cc35bSGeorge Liu     catch (const std::exception& e)
14525110c125STom Joseph     {
145338108d9dSVernon Mauery         lg2::error("Chassis Identify: Error Setting State {LED_STATE}: {ERROR}",
145438108d9dSVernon Mauery                    "LED_STATE", flag, "ERROR", e);
14556706c1ccSMarri Devender Rao         elog<InternalFailure>();
14566706c1ccSMarri Devender Rao     }
14576706c1ccSMarri Devender Rao }
14586706c1ccSMarri Devender Rao 
14596706c1ccSMarri Devender Rao /** @brief Callback method to turn off LED
14606706c1ccSMarri Devender Rao  */
enclosureIdentifyLedOff()14616706c1ccSMarri Devender Rao void enclosureIdentifyLedOff()
14626706c1ccSMarri Devender Rao {
14636706c1ccSMarri Devender Rao     try
14646706c1ccSMarri Devender Rao     {
1465f4e38515SYong Li         chassisIDState = ChassisIDState::off;
14666706c1ccSMarri Devender Rao         enclosureIdentifyLed(false);
14676706c1ccSMarri Devender Rao     }
14686706c1ccSMarri Devender Rao     catch (const InternalFailure& e)
14696706c1ccSMarri Devender Rao     {
14706706c1ccSMarri Devender Rao         report<InternalFailure>();
14716706c1ccSMarri Devender Rao     }
14726706c1ccSMarri Devender Rao }
14736706c1ccSMarri Devender Rao 
14746706c1ccSMarri Devender Rao /** @brief Create timer to turn on and off the enclosure LED
14756706c1ccSMarri Devender Rao  */
createIdentifyTimer()14766706c1ccSMarri Devender Rao void createIdentifyTimer()
14776706c1ccSMarri Devender Rao {
14786706c1ccSMarri Devender Rao     if (!identifyTimer)
14796706c1ccSMarri Devender Rao     {
14801181af74SVernon Mauery         identifyTimer =
148195655220SPatrick Williams             std::make_unique<sdbusplus::Timer>(enclosureIdentifyLedOff);
14826706c1ccSMarri Devender Rao     }
14836706c1ccSMarri Devender Rao }
14846706c1ccSMarri Devender Rao 
ipmiChassisIdentify(std::optional<uint8_t> interval,std::optional<uint8_t> force)1485400cc789SVernon Mauery ipmi::RspType<> ipmiChassisIdentify(std::optional<uint8_t> interval,
1486400cc789SVernon Mauery                                     std::optional<uint8_t> force)
14876706c1ccSMarri Devender Rao {
1488400cc789SVernon Mauery     uint8_t identifyInterval = interval.value_or(DEFAULT_IDENTIFY_TIME_OUT);
1489400cc789SVernon Mauery     bool forceIdentify = force.value_or(0) & 0x01;
1490bed2699fSTom Joseph 
14916706c1ccSMarri Devender Rao     if (identifyInterval || forceIdentify)
14926706c1ccSMarri Devender Rao     {
1493400cc789SVernon Mauery         // stop the timer if already started;
1494400cc789SVernon Mauery         // for force identify we should not turn off LED
14951181af74SVernon Mauery         identifyTimer->stop();
14966706c1ccSMarri Devender Rao         try
14976706c1ccSMarri Devender Rao         {
1498f4e38515SYong Li             chassisIDState = ChassisIDState::temporaryOn;
14996706c1ccSMarri Devender Rao             enclosureIdentifyLed(true);
15006706c1ccSMarri Devender Rao         }
15016706c1ccSMarri Devender Rao         catch (const InternalFailure& e)
15026706c1ccSMarri Devender Rao         {
15036706c1ccSMarri Devender Rao             report<InternalFailure>();
1504400cc789SVernon Mauery             return ipmi::responseResponseError();
15055110c125STom Joseph         }
15066706c1ccSMarri Devender Rao 
15075110c125STom Joseph         if (forceIdentify)
15085110c125STom Joseph         {
1509f4e38515SYong Li             chassisIDState = ChassisIDState::indefiniteOn;
1510400cc789SVernon Mauery             return ipmi::responseSuccess();
15115110c125STom Joseph         }
15126706c1ccSMarri Devender Rao         // start the timer
15136706c1ccSMarri Devender Rao         auto time = std::chrono::duration_cast<std::chrono::microseconds>(
15146706c1ccSMarri Devender Rao             std::chrono::seconds(identifyInterval));
15151181af74SVernon Mauery         identifyTimer->start(time);
15165110c125STom Joseph     }
1517bed2699fSTom Joseph     else if (!identifyInterval)
1518bed2699fSTom Joseph     {
15191181af74SVernon Mauery         identifyTimer->stop();
1520bed2699fSTom Joseph         enclosureIdentifyLedOff();
1521bed2699fSTom Joseph     }
1522400cc789SVernon Mauery     return ipmi::responseSuccess();
15235110c125STom Joseph }
15245110c125STom Joseph 
15258cc19362SDeepak Kodihalli namespace boot_options
15268cc19362SDeepak Kodihalli {
15278cc19362SDeepak Kodihalli 
1528523e2d1bSWilly Tu using namespace sdbusplus::server::xyz::openbmc_project::control::boot;
15298cc19362SDeepak Kodihalli using IpmiValue = uint8_t;
15308cc19362SDeepak Kodihalli constexpr auto ipmiDefault = 0;
15318cc19362SDeepak Kodihalli 
153296ef0282SKonstantin Aladyshev std::map<IpmiValue, Type::Types> typeIpmiToDbus = {{0x00, Type::Types::Legacy},
153396ef0282SKonstantin Aladyshev                                                    {0x01, Type::Types::EFI}};
153496ef0282SKonstantin Aladyshev 
15350b02be92SPatrick Venture std::map<IpmiValue, Source::Sources> sourceIpmiToDbus = {
15368cc19362SDeepak Kodihalli     {0x01, Source::Sources::Network},
15378cc19362SDeepak Kodihalli     {0x02, Source::Sources::Disk},
15388cc19362SDeepak Kodihalli     {0x05, Source::Sources::ExternalMedia},
153967c5e5d6SJia, chunhui     {0x0f, Source::Sources::RemovableMedia},
15400b02be92SPatrick Venture     {ipmiDefault, Source::Sources::Default}};
154198a23840SMatthew Barth 
15420b02be92SPatrick Venture std::map<IpmiValue, Mode::Modes> modeIpmiToDbus = {
15435833cb6eSYong Li #ifdef ENABLE_BOOT_FLAG_SAFE_MODE_SUPPORT
15448cc19362SDeepak Kodihalli     {0x03, Mode::Modes::Safe},
15455833cb6eSYong Li #endif // ENABLE_BOOT_SAFE_MODE_SUPPORT
15468cc19362SDeepak Kodihalli     {0x06, Mode::Modes::Setup},
15470b02be92SPatrick Venture     {ipmiDefault, Mode::Modes::Regular}};
154898a23840SMatthew Barth 
154996ef0282SKonstantin Aladyshev std::map<Type::Types, IpmiValue> typeDbusToIpmi = {{Type::Types::Legacy, 0x00},
155096ef0282SKonstantin Aladyshev                                                    {Type::Types::EFI, 0x01}};
155196ef0282SKonstantin Aladyshev 
15520b02be92SPatrick Venture std::map<Source::Sources, IpmiValue> sourceDbusToIpmi = {
15538cc19362SDeepak Kodihalli     {Source::Sources::Network, 0x01},
15548cc19362SDeepak Kodihalli     {Source::Sources::Disk, 0x02},
15558cc19362SDeepak Kodihalli     {Source::Sources::ExternalMedia, 0x05},
155667c5e5d6SJia, chunhui     {Source::Sources::RemovableMedia, 0x0f},
15570b02be92SPatrick Venture     {Source::Sources::Default, ipmiDefault}};
155898a23840SMatthew Barth 
15590b02be92SPatrick Venture std::map<Mode::Modes, IpmiValue> modeDbusToIpmi = {
15605833cb6eSYong Li #ifdef ENABLE_BOOT_FLAG_SAFE_MODE_SUPPORT
15618cc19362SDeepak Kodihalli     {Mode::Modes::Safe, 0x03},
15625833cb6eSYong Li #endif // ENABLE_BOOT_SAFE_MODE_SUPPORT
15638cc19362SDeepak Kodihalli     {Mode::Modes::Setup, 0x06},
15640b02be92SPatrick Venture     {Mode::Modes::Regular, ipmiDefault}};
156598a23840SMatthew Barth 
15668cc19362SDeepak Kodihalli } // namespace boot_options
156798a23840SMatthew Barth 
156808a080abSKonstantin Aladyshev /** @brief Get the property value for boot source
156908a080abSKonstantin Aladyshev  *  @param[in] ctx - context pointer
157008a080abSKonstantin Aladyshev  *  @param[out] source - boot source value
157108a080abSKonstantin Aladyshev  *  @return On failure return IPMI error.
157208a080abSKonstantin Aladyshev  */
getBootSource(ipmi::Context::ptr & ctx,Source::Sources & source)157308a080abSKonstantin Aladyshev static ipmi::Cc getBootSource(ipmi::Context::ptr& ctx, Source::Sources& source)
157408a080abSKonstantin Aladyshev {
157508a080abSKonstantin Aladyshev     using namespace chassis::internal;
157608a080abSKonstantin Aladyshev     std::string result;
157708a080abSKonstantin Aladyshev     std::string service;
15781318a5edSPatrick Williams     boost::system::error_code ec =
15791318a5edSPatrick Williams         getService(ctx, bootSourceIntf, bootSettingsPath, service);
158008a080abSKonstantin Aladyshev     if (!ec)
158108a080abSKonstantin Aladyshev     {
158208a080abSKonstantin Aladyshev         ec = ipmi::getDbusProperty(ctx, service, bootSettingsPath,
158308a080abSKonstantin Aladyshev                                    bootSourceIntf, "BootSource", result);
158408a080abSKonstantin Aladyshev         if (!ec)
158508a080abSKonstantin Aladyshev         {
158608a080abSKonstantin Aladyshev             source = Source::convertSourcesFromString(result);
158708a080abSKonstantin Aladyshev             return ipmi::ccSuccess;
158808a080abSKonstantin Aladyshev         }
158908a080abSKonstantin Aladyshev     }
159038108d9dSVernon Mauery     lg2::error("Error in BootSource Get: {ERROR}", "ERROR", ec.message());
159108a080abSKonstantin Aladyshev     return ipmi::ccUnspecifiedError;
159208a080abSKonstantin Aladyshev }
159308a080abSKonstantin Aladyshev 
15948171970aSMarri Devender Rao /** @brief Set the property value for boot source
1595e76a61a2SKonstantin Aladyshev  *  @param[in] ctx - context pointer
15968171970aSMarri Devender Rao  *  @param[in] source - boot source value
15978171970aSMarri Devender Rao  *  @return On failure return IPMI error.
15988171970aSMarri Devender Rao  */
setBootSource(ipmi::Context::ptr & ctx,const Source::Sources & source)15996088e9f7SJayaprakash Mutyala static ipmi::Cc setBootSource(ipmi::Context::ptr& ctx,
1600e76a61a2SKonstantin Aladyshev                               const Source::Sources& source)
16018171970aSMarri Devender Rao {
16028171970aSMarri Devender Rao     using namespace chassis::internal;
160308a080abSKonstantin Aladyshev     std::string service;
16041318a5edSPatrick Williams     boost::system::error_code ec =
16051318a5edSPatrick Williams         getService(ctx, bootSourceIntf, bootSettingsPath, service);
160608a080abSKonstantin Aladyshev     if (!ec)
160769e8e84dSKonstantin Aladyshev     {
160808a080abSKonstantin Aladyshev         ec = ipmi::setDbusProperty(ctx, service, bootSettingsPath,
160908a080abSKonstantin Aladyshev                                    bootSourceIntf, "BootSource",
161008a080abSKonstantin Aladyshev                                    convertForMessage(source));
161108a080abSKonstantin Aladyshev         if (!ec)
161208a080abSKonstantin Aladyshev         {
161308a080abSKonstantin Aladyshev             return ipmi::ccSuccess;
161408a080abSKonstantin Aladyshev         }
161508a080abSKonstantin Aladyshev     }
161638108d9dSVernon Mauery     lg2::error("Error in BootSource Set: {ERROR}", "ERROR", ec.message());
1617e76a61a2SKonstantin Aladyshev     return ipmi::ccUnspecifiedError;
16188171970aSMarri Devender Rao }
161908a080abSKonstantin Aladyshev 
162008a080abSKonstantin Aladyshev /** @brief Get the property value for boot mode
162108a080abSKonstantin Aladyshev  *  @param[in] ctx - context pointer
162208a080abSKonstantin Aladyshev  *  @param[out] mode - boot mode value
162308a080abSKonstantin Aladyshev  *  @return On failure return IPMI error.
162408a080abSKonstantin Aladyshev  */
getBootMode(ipmi::Context::ptr & ctx,Mode::Modes & mode)162508a080abSKonstantin Aladyshev static ipmi::Cc getBootMode(ipmi::Context::ptr& ctx, Mode::Modes& mode)
162608a080abSKonstantin Aladyshev {
162708a080abSKonstantin Aladyshev     using namespace chassis::internal;
162808a080abSKonstantin Aladyshev     std::string result;
162908a080abSKonstantin Aladyshev     std::string service;
16301318a5edSPatrick Williams     boost::system::error_code ec =
16311318a5edSPatrick Williams         getService(ctx, bootModeIntf, bootSettingsPath, service);
163208a080abSKonstantin Aladyshev     if (!ec)
163308a080abSKonstantin Aladyshev     {
163408a080abSKonstantin Aladyshev         ec = ipmi::getDbusProperty(ctx, service, bootSettingsPath, bootModeIntf,
163508a080abSKonstantin Aladyshev                                    "BootMode", result);
163608a080abSKonstantin Aladyshev         if (!ec)
163708a080abSKonstantin Aladyshev         {
163808a080abSKonstantin Aladyshev             mode = Mode::convertModesFromString(result);
1639e76a61a2SKonstantin Aladyshev             return ipmi::ccSuccess;
16408171970aSMarri Devender Rao         }
164108a080abSKonstantin Aladyshev     }
164238108d9dSVernon Mauery     lg2::error("Error in BootMode Get: {ERROR}", "ERROR", ec.message());
164308a080abSKonstantin Aladyshev     return ipmi::ccUnspecifiedError;
164408a080abSKonstantin Aladyshev }
16458171970aSMarri Devender Rao 
16468171970aSMarri Devender Rao /** @brief Set the property value for boot mode
1647e76a61a2SKonstantin Aladyshev  *  @param[in] ctx - context pointer
16488171970aSMarri Devender Rao  *  @param[in] mode - boot mode value
16498171970aSMarri Devender Rao  *  @return On failure return IPMI error.
16508171970aSMarri Devender Rao  */
setBootMode(ipmi::Context::ptr & ctx,const Mode::Modes & mode)1651e76a61a2SKonstantin Aladyshev static ipmi::Cc setBootMode(ipmi::Context::ptr& ctx, const Mode::Modes& mode)
16528171970aSMarri Devender Rao {
16538171970aSMarri Devender Rao     using namespace chassis::internal;
165408a080abSKonstantin Aladyshev     std::string service;
16551318a5edSPatrick Williams     boost::system::error_code ec =
16561318a5edSPatrick Williams         getService(ctx, bootModeIntf, bootSettingsPath, service);
165708a080abSKonstantin Aladyshev     if (!ec)
16588171970aSMarri Devender Rao     {
165908a080abSKonstantin Aladyshev         ec = ipmi::setDbusProperty(ctx, service, bootSettingsPath, bootModeIntf,
166008a080abSKonstantin Aladyshev                                    "BootMode", convertForMessage(mode));
166108a080abSKonstantin Aladyshev         if (!ec)
166208a080abSKonstantin Aladyshev         {
166308a080abSKonstantin Aladyshev             return ipmi::ccSuccess;
166408a080abSKonstantin Aladyshev         }
166508a080abSKonstantin Aladyshev     }
166638108d9dSVernon Mauery     lg2::error("Error in BootMode Set: {ERROR}", "ERROR", ec.message());
1667bfd8fc4bSjayaprakash Mutyala     return ipmi::ccUnspecifiedError;
16688171970aSMarri Devender Rao }
166908a080abSKonstantin Aladyshev 
167008a080abSKonstantin Aladyshev /** @brief Get the property value for boot type
167108a080abSKonstantin Aladyshev  *  @param[in] ctx - context pointer
167208a080abSKonstantin Aladyshev  *  @param[out] type - boot type value
167308a080abSKonstantin Aladyshev  *  @return On failure return IPMI error.
167408a080abSKonstantin Aladyshev  */
getBootType(ipmi::Context::ptr & ctx,Type::Types & type)167508a080abSKonstantin Aladyshev static ipmi::Cc getBootType(ipmi::Context::ptr& ctx, Type::Types& type)
167608a080abSKonstantin Aladyshev {
167708a080abSKonstantin Aladyshev     using namespace chassis::internal;
167808a080abSKonstantin Aladyshev     std::string result;
167908a080abSKonstantin Aladyshev     std::string service;
16801318a5edSPatrick Williams     boost::system::error_code ec =
16811318a5edSPatrick Williams         getService(ctx, bootTypeIntf, bootSettingsPath, service);
168208a080abSKonstantin Aladyshev 
168308a080abSKonstantin Aladyshev     // Don't throw error if BootType interface is not present.
168408a080abSKonstantin Aladyshev     // This interface is not relevant for some Host architectures
168508a080abSKonstantin Aladyshev     // (for example POWER). In this case we don't won't IPMI to
168608a080abSKonstantin Aladyshev     // return an error, but simply return bootType as EFI.
168708a080abSKonstantin Aladyshev     type = Type::Types::EFI;
168808a080abSKonstantin Aladyshev     if (!ec)
168908a080abSKonstantin Aladyshev     {
169008a080abSKonstantin Aladyshev         ec = ipmi::getDbusProperty(ctx, service, bootSettingsPath, bootTypeIntf,
169108a080abSKonstantin Aladyshev                                    "BootType", result);
169208a080abSKonstantin Aladyshev         if (ec)
169308a080abSKonstantin Aladyshev         {
169438108d9dSVernon Mauery             lg2::error("Error in BootType Get: {ERROR}", "ERROR", ec.message());
169508a080abSKonstantin Aladyshev             return ipmi::ccUnspecifiedError;
169608a080abSKonstantin Aladyshev         }
169708a080abSKonstantin Aladyshev         type = Type::convertTypesFromString(result);
169808a080abSKonstantin Aladyshev     }
169908a080abSKonstantin Aladyshev 
1700bfd8fc4bSjayaprakash Mutyala     return ipmi::ccSuccess;
17018171970aSMarri Devender Rao }
17028171970aSMarri Devender Rao 
170396ef0282SKonstantin Aladyshev /** @brief Set the property value for boot type
1704e76a61a2SKonstantin Aladyshev  *  @param[in] ctx - context pointer
170596ef0282SKonstantin Aladyshev  *  @param[in] type - boot type value
170696ef0282SKonstantin Aladyshev  *  @return On failure return IPMI error.
170796ef0282SKonstantin Aladyshev  */
setBootType(ipmi::Context::ptr & ctx,const Type::Types & type)1708e76a61a2SKonstantin Aladyshev static ipmi::Cc setBootType(ipmi::Context::ptr& ctx, const Type::Types& type)
170996ef0282SKonstantin Aladyshev {
171096ef0282SKonstantin Aladyshev     using namespace chassis::internal;
171108a080abSKonstantin Aladyshev     std::string service;
17121318a5edSPatrick Williams     boost::system::error_code ec =
17131318a5edSPatrick Williams         getService(ctx, bootTypeIntf, bootSettingsPath, service);
171408a080abSKonstantin Aladyshev     if (!ec)
171596ef0282SKonstantin Aladyshev     {
171608a080abSKonstantin Aladyshev         ec = ipmi::setDbusProperty(ctx, service, bootSettingsPath, bootTypeIntf,
171708a080abSKonstantin Aladyshev                                    "BootType", convertForMessage(type));
1718e76a61a2SKonstantin Aladyshev         if (ec)
171996ef0282SKonstantin Aladyshev         {
172038108d9dSVernon Mauery             lg2::error("Error in BootType Set: {ERROR}", "ERROR", ec.message());
172196ef0282SKonstantin Aladyshev             return ipmi::ccUnspecifiedError;
172296ef0282SKonstantin Aladyshev         }
172308a080abSKonstantin Aladyshev     }
172408a080abSKonstantin Aladyshev     // Don't throw error if BootType interface is not present.
172508a080abSKonstantin Aladyshev     // This interface is not relevant for some Host architectures
172608a080abSKonstantin Aladyshev     // (for example POWER). In this case we don't won't IPMI to
172708a080abSKonstantin Aladyshev     // return an error, but want to just skip this function.
172896ef0282SKonstantin Aladyshev     return ipmi::ccSuccess;
172996ef0282SKonstantin Aladyshev }
173096ef0282SKonstantin Aladyshev 
173108a080abSKonstantin Aladyshev /** @brief Get the property value for boot override enable
173208a080abSKonstantin Aladyshev  *  @param[in] ctx - context pointer
173308a080abSKonstantin Aladyshev  *  @param[out] enable - boot override enable
173408a080abSKonstantin Aladyshev  *  @return On failure return IPMI error.
173508a080abSKonstantin Aladyshev  */
getBootEnable(ipmi::Context::ptr & ctx,bool & enable)173608a080abSKonstantin Aladyshev static ipmi::Cc getBootEnable(ipmi::Context::ptr& ctx, bool& enable)
173708a080abSKonstantin Aladyshev {
173808a080abSKonstantin Aladyshev     using namespace chassis::internal;
173908a080abSKonstantin Aladyshev     std::string result;
174008a080abSKonstantin Aladyshev     std::string service;
17411318a5edSPatrick Williams     boost::system::error_code ec =
17421318a5edSPatrick Williams         getService(ctx, bootEnableIntf, bootSettingsPath, service);
174308a080abSKonstantin Aladyshev     if (!ec)
174408a080abSKonstantin Aladyshev     {
174508a080abSKonstantin Aladyshev         ec = ipmi::getDbusProperty(ctx, service, bootSettingsPath,
174608a080abSKonstantin Aladyshev                                    bootEnableIntf, "Enabled", enable);
174708a080abSKonstantin Aladyshev         if (!ec)
174808a080abSKonstantin Aladyshev         {
174908a080abSKonstantin Aladyshev             return ipmi::ccSuccess;
175008a080abSKonstantin Aladyshev         }
175108a080abSKonstantin Aladyshev     }
175238108d9dSVernon Mauery     lg2::error("Error in Boot Override Enable Get: {ERROR}", "ERROR",
175338108d9dSVernon Mauery                ec.message());
175408a080abSKonstantin Aladyshev     return ipmi::ccUnspecifiedError;
175508a080abSKonstantin Aladyshev }
175608a080abSKonstantin Aladyshev 
175708a080abSKonstantin Aladyshev /** @brief Set the property value for boot override enable
175808a080abSKonstantin Aladyshev  *  @param[in] ctx - context pointer
175908a080abSKonstantin Aladyshev  *  @param[in] enable - boot override enable
176008a080abSKonstantin Aladyshev  *  @return On failure return IPMI error.
176108a080abSKonstantin Aladyshev  */
setBootEnable(ipmi::Context::ptr & ctx,const bool & enable)176208a080abSKonstantin Aladyshev static ipmi::Cc setBootEnable(ipmi::Context::ptr& ctx, const bool& enable)
176308a080abSKonstantin Aladyshev {
176408a080abSKonstantin Aladyshev     using namespace chassis::internal;
176508a080abSKonstantin Aladyshev     std::string service;
17661318a5edSPatrick Williams     boost::system::error_code ec =
17671318a5edSPatrick Williams         getService(ctx, bootEnableIntf, bootSettingsPath, service);
176808a080abSKonstantin Aladyshev     if (!ec)
176908a080abSKonstantin Aladyshev     {
177008a080abSKonstantin Aladyshev         ec = ipmi::setDbusProperty(ctx, service, bootSettingsPath,
177108a080abSKonstantin Aladyshev                                    bootEnableIntf, "Enabled", enable);
177208a080abSKonstantin Aladyshev         if (!ec)
177308a080abSKonstantin Aladyshev         {
177408a080abSKonstantin Aladyshev             return ipmi::ccSuccess;
177508a080abSKonstantin Aladyshev         }
177608a080abSKonstantin Aladyshev     }
177738108d9dSVernon Mauery     lg2::error("Error in Boot Source Override Enable Set: {ERROR}", "ERROR",
177838108d9dSVernon Mauery                ec.message());
177908a080abSKonstantin Aladyshev     return ipmi::ccUnspecifiedError;
178008a080abSKonstantin Aladyshev }
178108a080abSKonstantin Aladyshev 
178208a080abSKonstantin Aladyshev /** @brief Get the property value for boot override one-time
178308a080abSKonstantin Aladyshev  *  @param[in] ctx - context pointer
178408a080abSKonstantin Aladyshev  *  @param[out] onetime - boot override one-time
178508a080abSKonstantin Aladyshev  *  @return On failure return IPMI error.
178608a080abSKonstantin Aladyshev  */
getBootOneTime(ipmi::Context::ptr & ctx,bool & onetime)178708a080abSKonstantin Aladyshev static ipmi::Cc getBootOneTime(ipmi::Context::ptr& ctx, bool& onetime)
178808a080abSKonstantin Aladyshev {
178908a080abSKonstantin Aladyshev     using namespace chassis::internal;
179008a080abSKonstantin Aladyshev     std::string result;
179108a080abSKonstantin Aladyshev     std::string service;
17921318a5edSPatrick Williams     boost::system::error_code ec =
17931318a5edSPatrick Williams         getService(ctx, bootOneTimeIntf, bootSettingsOneTimePath, service);
179408a080abSKonstantin Aladyshev     if (!ec)
179508a080abSKonstantin Aladyshev     {
179608a080abSKonstantin Aladyshev         ec = ipmi::getDbusProperty(ctx, service, bootSettingsOneTimePath,
179708a080abSKonstantin Aladyshev                                    bootOneTimeIntf, "Enabled", onetime);
179808a080abSKonstantin Aladyshev         if (!ec)
179908a080abSKonstantin Aladyshev         {
180008a080abSKonstantin Aladyshev             return ipmi::ccSuccess;
180108a080abSKonstantin Aladyshev         }
180208a080abSKonstantin Aladyshev     }
180338108d9dSVernon Mauery     lg2::error("Error in Boot Override OneTime Get: {ERROR}", "ERROR",
180438108d9dSVernon Mauery                ec.message());
180508a080abSKonstantin Aladyshev     return ipmi::ccUnspecifiedError;
180608a080abSKonstantin Aladyshev }
180708a080abSKonstantin Aladyshev 
180808a080abSKonstantin Aladyshev /** @brief Set the property value for boot override one-time
180908a080abSKonstantin Aladyshev  *  @param[in] ctx - context pointer
181008a080abSKonstantin Aladyshev  *  @param[in] onetime - boot override one-time
181108a080abSKonstantin Aladyshev  *  @return On failure return IPMI error.
181208a080abSKonstantin Aladyshev  */
setBootOneTime(ipmi::Context::ptr & ctx,const bool & onetime)181308a080abSKonstantin Aladyshev static ipmi::Cc setBootOneTime(ipmi::Context::ptr& ctx, const bool& onetime)
181408a080abSKonstantin Aladyshev {
181508a080abSKonstantin Aladyshev     using namespace chassis::internal;
181608a080abSKonstantin Aladyshev     std::string service;
18171318a5edSPatrick Williams     boost::system::error_code ec =
18181318a5edSPatrick Williams         getService(ctx, bootOneTimeIntf, bootSettingsOneTimePath, service);
181908a080abSKonstantin Aladyshev     if (!ec)
182008a080abSKonstantin Aladyshev     {
182108a080abSKonstantin Aladyshev         ec = ipmi::setDbusProperty(ctx, service, bootSettingsOneTimePath,
182208a080abSKonstantin Aladyshev                                    bootOneTimeIntf, "Enabled", onetime);
182308a080abSKonstantin Aladyshev         if (!ec)
182408a080abSKonstantin Aladyshev         {
182508a080abSKonstantin Aladyshev             return ipmi::ccSuccess;
182608a080abSKonstantin Aladyshev         }
182708a080abSKonstantin Aladyshev     }
182838108d9dSVernon Mauery     lg2::error("Error in Boot Source Override OneTime Set: {ERROR}", "ERROR",
182938108d9dSVernon Mauery                ec.message());
183008a080abSKonstantin Aladyshev     return ipmi::ccUnspecifiedError;
183108a080abSKonstantin Aladyshev }
183208a080abSKonstantin Aladyshev 
1833ab369285Shuanghe static constexpr uint8_t setComplete = 0x0;
1834ab369285Shuanghe static constexpr uint8_t setInProgress = 0x1;
1835ab369285Shuanghe static uint8_t transferStatus = setComplete;
183686ac4991SChen Yugang static uint8_t bootFlagValidBitClr = 0;
183738ffafcfSHieu Huynh static uint5_t bootInitiatorAckData = 0x0;
18381982a3fbSHieu Huynh static bool cmosClear = false;
1839ab369285Shuanghe 
1840d1ef877fSJayaprakash Mutyala /** @brief implements the Get Chassis system boot option
1841e76a61a2SKonstantin Aladyshev  *  @param ctx - context pointer
1842d1ef877fSJayaprakash Mutyala  *  @param bootOptionParameter   - boot option parameter selector
1843d1ef877fSJayaprakash Mutyala  *  @param reserved1    - reserved bit
1844d1ef877fSJayaprakash Mutyala  *  @param setSelector  - selects a particular block or set of parameters
1845d1ef877fSJayaprakash Mutyala  *                        under the given parameter selector
1846d1ef877fSJayaprakash Mutyala  *                        write as 00h if parameter doesn't use a setSelector
1847d1ef877fSJayaprakash Mutyala  *  @param blockSelector- selects a particular block within a set of
1848d1ef877fSJayaprakash Mutyala  *                        parameters write as 00h if parameter doesn't use a
1849d1ef877fSJayaprakash Mutyala  *                        blockSelector
1850d1ef877fSJayaprakash Mutyala  *
1851d1ef877fSJayaprakash Mutyala  *  @return IPMI completion code plus response data
1852d1ef877fSJayaprakash Mutyala  *  @return Payload contains below parameters:
1853d1ef877fSJayaprakash Mutyala  *   version             - parameter version
1854d1ef877fSJayaprakash Mutyala  *   bootOptionParameter - boot option parameter selector
18558b1c303eSPatrick Venture  *   parmIndicator - parameter valid/invalid indicator
1856d1ef877fSJayaprakash Mutyala  *   data          - configuration parameter data
1857d1ef877fSJayaprakash Mutyala  */
ipmiChassisGetSysBootOptions(ipmi::Context::ptr ctx,uint7_t bootOptionParameter,bool reserved1,uint8_t setSelector,uint8_t blockSelector)18581318a5edSPatrick Williams ipmi::RspType<ipmi::message::Payload> ipmiChassisGetSysBootOptions(
18591318a5edSPatrick Williams     ipmi::Context::ptr ctx, uint7_t bootOptionParameter, bool reserved1,
186011d68897SWilly Tu     [[maybe_unused]] uint8_t setSelector,
186111d68897SWilly Tu     [[maybe_unused]] uint8_t blockSelector)
186298a23840SMatthew Barth {
186308a080abSKonstantin Aladyshev     ipmi::Cc rc;
1864d1ef877fSJayaprakash Mutyala     if (reserved1)
1865d1ef877fSJayaprakash Mutyala     {
1866d1ef877fSJayaprakash Mutyala         return ipmi::responseInvalidFieldRequest();
1867d1ef877fSJayaprakash Mutyala     }
1868d1ef877fSJayaprakash Mutyala 
1869d1ef877fSJayaprakash Mutyala     constexpr uint4_t version = 0x01;
1870d1ef877fSJayaprakash Mutyala     ipmi::message::Payload response;
1871d1ef877fSJayaprakash Mutyala     response.pack(version, uint4_t{});
18728cc19362SDeepak Kodihalli     using namespace boot_options;
1873d1ef877fSJayaprakash Mutyala 
18748cc19362SDeepak Kodihalli     IpmiValue bootOption = ipmiDefault;
187598a23840SMatthew Barth 
18767a0e5dfcSWilliam A. Kennington III     if (types::enum_cast<BootOptionParameter>(bootOptionParameter) ==
18777a0e5dfcSWilliam A. Kennington III         BootOptionParameter::setInProgress)
1878ab369285Shuanghe     {
1879ab369285Shuanghe         response.pack(bootOptionParameter, reserved1, transferStatus);
1880ab369285Shuanghe         return ipmi::responseSuccess(std::move(response));
1881ab369285Shuanghe     }
1882ab369285Shuanghe 
18837a0e5dfcSWilliam A. Kennington III     if (types::enum_cast<BootOptionParameter>(bootOptionParameter) ==
18847a0e5dfcSWilliam A. Kennington III         BootOptionParameter::bootInfo)
18850213f901SJohn Wang     {
18860213f901SJohn Wang         constexpr uint8_t writeMask = 0;
188738ffafcfSHieu Huynh         response.pack(bootOptionParameter, reserved1, writeMask,
188838ffafcfSHieu Huynh                       bootInitiatorAckData);
18890213f901SJohn Wang         return ipmi::responseSuccess(std::move(response));
18900213f901SJohn Wang     }
18910213f901SJohn Wang 
189286ac4991SChen Yugang     if (types::enum_cast<BootOptionParameter>(bootOptionParameter) ==
189386ac4991SChen Yugang         BootOptionParameter::bootFlagValidClr)
189486ac4991SChen Yugang     {
189586ac4991SChen Yugang         response.pack(bootOptionParameter, reserved1,
189686ac4991SChen Yugang                       uint5_t{bootFlagValidBitClr}, uint3_t{});
189786ac4991SChen Yugang         return ipmi::responseSuccess(std::move(response));
189886ac4991SChen Yugang     }
189986ac4991SChen Yugang 
190098a23840SMatthew Barth     /*
190198a23840SMatthew Barth      * Parameter #5 means boot flags. Please refer to 28.13 of ipmi doc.
190298a23840SMatthew Barth      * This is the only parameter used by petitboot.
190398a23840SMatthew Barth      */
19047a0e5dfcSWilliam A. Kennington III     if (types::enum_cast<BootOptionParameter>(bootOptionParameter) ==
19057a0e5dfcSWilliam A. Kennington III         BootOptionParameter::bootFlags)
19060b02be92SPatrick Venture     {
19078cc19362SDeepak Kodihalli         using namespace chassis::internal;
19088cc19362SDeepak Kodihalli         using namespace chassis::internal::cache;
190998a23840SMatthew Barth 
191013791bd5SDeepak Kodihalli         try
191113791bd5SDeepak Kodihalli         {
191208a080abSKonstantin Aladyshev             Source::Sources bootSource;
191308a080abSKonstantin Aladyshev             rc = getBootSource(ctx, bootSource);
191408a080abSKonstantin Aladyshev             if (rc != ipmi::ccSuccess)
19158cc19362SDeepak Kodihalli             {
191608a080abSKonstantin Aladyshev                 return ipmi::response(rc);
19178cc19362SDeepak Kodihalli             }
191898a23840SMatthew Barth 
191996ef0282SKonstantin Aladyshev             Type::Types bootType;
192008a080abSKonstantin Aladyshev             rc = getBootType(ctx, bootType);
192108a080abSKonstantin Aladyshev             if (rc != ipmi::ccSuccess)
192296ef0282SKonstantin Aladyshev             {
192308a080abSKonstantin Aladyshev                 return ipmi::response(rc);
192496ef0282SKonstantin Aladyshev             }
192596ef0282SKonstantin Aladyshev 
192608a080abSKonstantin Aladyshev             Mode::Modes bootMode;
192708a080abSKonstantin Aladyshev             rc = getBootMode(ctx, bootMode);
192808a080abSKonstantin Aladyshev             if (rc != ipmi::ccSuccess)
19298cc19362SDeepak Kodihalli             {
193008a080abSKonstantin Aladyshev                 return ipmi::response(rc);
19318cc19362SDeepak Kodihalli             }
193298a23840SMatthew Barth 
19338cc19362SDeepak Kodihalli             bootOption = sourceDbusToIpmi.at(bootSource);
19348cc19362SDeepak Kodihalli             if ((Mode::Modes::Regular == bootMode) &&
19358cc19362SDeepak Kodihalli                 (Source::Sources::Default == bootSource))
19368cc19362SDeepak Kodihalli             {
19378cc19362SDeepak Kodihalli                 bootOption = ipmiDefault;
19388cc19362SDeepak Kodihalli             }
19398cc19362SDeepak Kodihalli             else if (Source::Sources::Default == bootSource)
19408cc19362SDeepak Kodihalli             {
19418cc19362SDeepak Kodihalli                 bootOption = modeDbusToIpmi.at(bootMode);
19428cc19362SDeepak Kodihalli             }
194398a23840SMatthew Barth 
194496ef0282SKonstantin Aladyshev             IpmiValue biosBootType = typeDbusToIpmi.at(bootType);
194508a080abSKonstantin Aladyshev 
194608a080abSKonstantin Aladyshev             bool oneTimeEnabled;
194708a080abSKonstantin Aladyshev             rc = getBootOneTime(ctx, oneTimeEnabled);
194808a080abSKonstantin Aladyshev             if (rc != ipmi::ccSuccess)
194908a080abSKonstantin Aladyshev             {
195008a080abSKonstantin Aladyshev                 return ipmi::response(rc);
195108a080abSKonstantin Aladyshev             }
195208a080abSKonstantin Aladyshev 
195396ef0282SKonstantin Aladyshev             uint1_t permanent = oneTimeEnabled ? 0 : 1;
195408a080abSKonstantin Aladyshev 
195508a080abSKonstantin Aladyshev             bool valid;
195608a080abSKonstantin Aladyshev             rc = getBootEnable(ctx, valid);
195708a080abSKonstantin Aladyshev             if (rc != ipmi::ccSuccess)
195808a080abSKonstantin Aladyshev             {
195908a080abSKonstantin Aladyshev                 return ipmi::response(rc);
196008a080abSKonstantin Aladyshev             }
196108a080abSKonstantin Aladyshev 
196208a080abSKonstantin Aladyshev             uint1_t validFlag = valid ? 1 : 0;
196396ef0282SKonstantin Aladyshev 
196496ef0282SKonstantin Aladyshev             response.pack(bootOptionParameter, reserved1, uint5_t{},
196596ef0282SKonstantin Aladyshev                           uint1_t{biosBootType}, uint1_t{permanent},
196696ef0282SKonstantin Aladyshev                           uint1_t{validFlag}, uint2_t{}, uint4_t{bootOption},
19671982a3fbSHieu Huynh                           uint1_t{}, cmosClear, uint8_t{}, uint8_t{},
19681982a3fbSHieu Huynh                           uint8_t{});
1969d1ef877fSJayaprakash Mutyala             return ipmi::responseSuccess(std::move(response));
197098a23840SMatthew Barth         }
1971a2ad2da8SPatrick Williams         catch (const InternalFailure& e)
197213791bd5SDeepak Kodihalli         {
1973225dec85SJames Feist             cache::objectsPtr.reset();
197413791bd5SDeepak Kodihalli             report<InternalFailure>();
1975d1ef877fSJayaprakash Mutyala             return ipmi::responseUnspecifiedError();
197613791bd5SDeepak Kodihalli         }
19770b02be92SPatrick Venture     }
1978d1ef877fSJayaprakash Mutyala     else
1979d1ef877fSJayaprakash Mutyala     {
1980d1ef877fSJayaprakash Mutyala         if ((bootOptionParameter >= oemParmStart) &&
1981d1ef877fSJayaprakash Mutyala             (bootOptionParameter <= oemParmEnd))
1982d1ef877fSJayaprakash Mutyala         {
19837a0e5dfcSWilliam A. Kennington III             if (types::enum_cast<BootOptionParameter>(bootOptionParameter) ==
19847a0e5dfcSWilliam A. Kennington III                 BootOptionParameter::opalNetworkSettings)
19850b02be92SPatrick Venture             {
1986d1ef877fSJayaprakash Mutyala                 response.pack(bootOptionParameter, reserved1);
1987d1ef877fSJayaprakash Mutyala                 int ret = getHostNetworkData(response);
19880b02be92SPatrick Venture                 if (ret < 0)
19890b02be92SPatrick Venture                 {
1990d1ef877fSJayaprakash Mutyala                     response.trailingOk = true;
199138108d9dSVernon Mauery                     lg2::error(
1992d1ef877fSJayaprakash Mutyala                         "getHostNetworkData failed for GetSysBootOptions.");
1993d1ef877fSJayaprakash Mutyala                     return ipmi::responseUnspecifiedError();
19940b02be92SPatrick Venture                 }
19950b02be92SPatrick Venture                 else
1996d1ef877fSJayaprakash Mutyala                 {
1997d1ef877fSJayaprakash Mutyala                     return ipmi::responseSuccess(std::move(response));
1998fd28dd7aSRatan Gupta                 }
1999d1ef877fSJayaprakash Mutyala             }
200043a88109SJayaprakash Mutyala             else
200143a88109SJayaprakash Mutyala             {
200238108d9dSVernon Mauery                 lg2::error(
200338108d9dSVernon Mauery                     "ipmiChassisGetSysBootOptions: Unsupported parameter {PARAM}",
200438108d9dSVernon Mauery                     "PARAM", lg2::hex,
200538108d9dSVernon Mauery                     static_cast<uint8_t>(bootOptionParameter));
200643a88109SJayaprakash Mutyala                 return ipmi::responseParmNotSupported();
200743a88109SJayaprakash Mutyala             }
2008d1ef877fSJayaprakash Mutyala         }
20090b02be92SPatrick Venture         else
20100b02be92SPatrick Venture         {
201138108d9dSVernon Mauery             lg2::error(
201238108d9dSVernon Mauery                 "ipmiChassisGetSysBootOptions: Unsupported parameter {PARAM}",
201338108d9dSVernon Mauery                 "PARAM", lg2::hex, static_cast<uint8_t>(bootOptionParameter));
20146088e9f7SJayaprakash Mutyala             return ipmi::responseParmNotSupported();
201598a23840SMatthew Barth         }
2016fd28dd7aSRatan Gupta     }
2017d1ef877fSJayaprakash Mutyala     return ipmi::responseUnspecifiedError();
201898a23840SMatthew Barth }
201998a23840SMatthew Barth 
ipmiChassisSetSysBootOptions(ipmi::Context::ptr ctx,uint7_t parameterSelector,bool,ipmi::message::Payload & data)2020bfd8fc4bSjayaprakash Mutyala ipmi::RspType<> ipmiChassisSetSysBootOptions(ipmi::Context::ptr ctx,
202111d68897SWilly Tu                                              uint7_t parameterSelector, bool,
2022bfd8fc4bSjayaprakash Mutyala                                              ipmi::message::Payload& data)
202398a23840SMatthew Barth {
20248cc19362SDeepak Kodihalli     using namespace boot_options;
2025bfd8fc4bSjayaprakash Mutyala     ipmi::Cc rc;
202698a23840SMatthew Barth 
20277a0e5dfcSWilliam A. Kennington III     if (types::enum_cast<BootOptionParameter>(parameterSelector) ==
20287a0e5dfcSWilliam A. Kennington III         BootOptionParameter::setInProgress)
2029ab369285Shuanghe     {
2030ab369285Shuanghe         uint2_t setInProgressFlag;
2031ab369285Shuanghe         uint6_t rsvd;
2032ab369285Shuanghe         if (data.unpack(setInProgressFlag, rsvd) != 0 || !data.fullyUnpacked())
2033ab369285Shuanghe         {
2034ab369285Shuanghe             return ipmi::responseReqDataLenInvalid();
2035ab369285Shuanghe         }
2036ab369285Shuanghe         if (rsvd)
2037ab369285Shuanghe         {
2038ab369285Shuanghe             return ipmi::responseInvalidFieldRequest();
2039ab369285Shuanghe         }
2040ab369285Shuanghe         if ((transferStatus == setInProgress) &&
2041ab369285Shuanghe             (static_cast<uint8_t>(setInProgressFlag) != setComplete))
2042ab369285Shuanghe         {
2043ab369285Shuanghe             return ipmi::response(IPMI_CC_FAIL_SET_IN_PROGRESS);
2044ab369285Shuanghe         }
2045ab369285Shuanghe         transferStatus = static_cast<uint8_t>(setInProgressFlag);
2046ab369285Shuanghe         return ipmi::responseSuccess();
2047ab369285Shuanghe     }
2048ab369285Shuanghe 
204998a23840SMatthew Barth     /*  000101
205098a23840SMatthew Barth      * Parameter #5 means boot flags. Please refer to 28.13 of ipmi doc.
205198a23840SMatthew Barth      * This is the only parameter used by petitboot.
205298a23840SMatthew Barth      */
2053fd28dd7aSRatan Gupta 
20547a0e5dfcSWilliam A. Kennington III     if (types::enum_cast<BootOptionParameter>(parameterSelector) ==
20557a0e5dfcSWilliam A. Kennington III         BootOptionParameter::bootFlags)
20568cc19362SDeepak Kodihalli     {
2057bfd8fc4bSjayaprakash Mutyala         uint5_t rsvd;
2058bfd8fc4bSjayaprakash Mutyala         bool validFlag;
2059bfd8fc4bSjayaprakash Mutyala         bool permanent;
2060bfd8fc4bSjayaprakash Mutyala         bool biosBootType;
2061bfd8fc4bSjayaprakash Mutyala         bool lockOutResetButton;
2062bfd8fc4bSjayaprakash Mutyala         bool screenBlank;
2063bfd8fc4bSjayaprakash Mutyala         uint4_t bootDeviceSelector;
2064bfd8fc4bSjayaprakash Mutyala         bool lockKeyboard;
2065bfd8fc4bSjayaprakash Mutyala         uint8_t data3;
2066bfd8fc4bSjayaprakash Mutyala         uint4_t biosInfo;
2067bfd8fc4bSjayaprakash Mutyala         uint4_t rsvd1;
2068bfd8fc4bSjayaprakash Mutyala         uint5_t deviceInstance;
2069bfd8fc4bSjayaprakash Mutyala         uint3_t rsvd2;
2070bfd8fc4bSjayaprakash Mutyala 
2071bfd8fc4bSjayaprakash Mutyala         if (data.unpack(rsvd, biosBootType, permanent, validFlag,
2072bfd8fc4bSjayaprakash Mutyala                         lockOutResetButton, screenBlank, bootDeviceSelector,
2073bfd8fc4bSjayaprakash Mutyala                         lockKeyboard, cmosClear, data3, biosInfo, rsvd1,
2074bfd8fc4bSjayaprakash Mutyala                         deviceInstance, rsvd2) != 0 ||
2075bfd8fc4bSjayaprakash Mutyala             !data.fullyUnpacked())
2076bfd8fc4bSjayaprakash Mutyala         {
2077bfd8fc4bSjayaprakash Mutyala             return ipmi::responseReqDataLenInvalid();
2078bfd8fc4bSjayaprakash Mutyala         }
2079bfd8fc4bSjayaprakash Mutyala         if (rsvd || rsvd1 || rsvd2)
2080bfd8fc4bSjayaprakash Mutyala         {
2081bfd8fc4bSjayaprakash Mutyala             return ipmi::responseInvalidFieldRequest();
2082bfd8fc4bSjayaprakash Mutyala         }
2083bfd8fc4bSjayaprakash Mutyala 
20848cc19362SDeepak Kodihalli         using namespace chassis::internal;
20858cc19362SDeepak Kodihalli         using namespace chassis::internal::cache;
208613791bd5SDeepak Kodihalli 
208713791bd5SDeepak Kodihalli         try
208813791bd5SDeepak Kodihalli         {
208908a080abSKonstantin Aladyshev             rc = setBootOneTime(ctx, !permanent);
209008a080abSKonstantin Aladyshev             if (rc != ipmi::ccSuccess)
209169e8e84dSKonstantin Aladyshev             {
209208a080abSKonstantin Aladyshev                 return ipmi::response(rc);
209308a080abSKonstantin Aladyshev             }
2094afd45db1SVernon Mauery 
209508a080abSKonstantin Aladyshev             rc = setBootEnable(ctx, validFlag);
209608a080abSKonstantin Aladyshev             if (rc != ipmi::ccSuccess)
209708a080abSKonstantin Aladyshev             {
209808a080abSKonstantin Aladyshev                 return ipmi::response(rc);
209957e8eb7aSTom Joseph             }
210057e8eb7aSTom Joseph 
2101bfd8fc4bSjayaprakash Mutyala             auto modeItr =
2102bfd8fc4bSjayaprakash Mutyala                 modeIpmiToDbus.find(static_cast<uint8_t>(bootDeviceSelector));
210396ef0282SKonstantin Aladyshev             auto typeItr =
210496ef0282SKonstantin Aladyshev                 typeIpmiToDbus.find(static_cast<uint8_t>(biosBootType));
2105bfd8fc4bSjayaprakash Mutyala             auto sourceItr =
2106bfd8fc4bSjayaprakash Mutyala                 sourceIpmiToDbus.find(static_cast<uint8_t>(bootDeviceSelector));
210713791bd5SDeepak Kodihalli             if (sourceIpmiToDbus.end() != sourceItr)
21088cc19362SDeepak Kodihalli             {
2109e76a61a2SKonstantin Aladyshev                 rc = setBootSource(ctx, sourceItr->second);
2110bfd8fc4bSjayaprakash Mutyala                 if (rc != ipmi::ccSuccess)
21118cc19362SDeepak Kodihalli                 {
211208a080abSKonstantin Aladyshev                     return ipmi::response(rc);
21138cc19362SDeepak Kodihalli                 }
211454fa1306SMarri Devender Rao                 // If a set boot device is mapping to a boot source, then reset
211554fa1306SMarri Devender Rao                 // the boot mode D-Bus property to default.
211654fa1306SMarri Devender Rao                 // This way the ipmid code can determine which property is not
211754fa1306SMarri Devender Rao                 // at the default value
211854fa1306SMarri Devender Rao                 if (sourceItr->second != Source::Sources::Default)
211954fa1306SMarri Devender Rao                 {
212008a080abSKonstantin Aladyshev                     rc = setBootMode(ctx, Mode::Modes::Regular);
212108a080abSKonstantin Aladyshev                     if (rc != ipmi::ccSuccess)
212208a080abSKonstantin Aladyshev                     {
212308a080abSKonstantin Aladyshev                         return ipmi::response(rc);
212408a080abSKonstantin Aladyshev                     }
212554fa1306SMarri Devender Rao                 }
212613791bd5SDeepak Kodihalli             }
212796ef0282SKonstantin Aladyshev 
212896ef0282SKonstantin Aladyshev             if (typeIpmiToDbus.end() != typeItr)
212996ef0282SKonstantin Aladyshev             {
2130e76a61a2SKonstantin Aladyshev                 rc = setBootType(ctx, typeItr->second);
213196ef0282SKonstantin Aladyshev                 if (rc != ipmi::ccSuccess)
213296ef0282SKonstantin Aladyshev                 {
213308a080abSKonstantin Aladyshev                     return ipmi::response(rc);
213496ef0282SKonstantin Aladyshev                 }
213596ef0282SKonstantin Aladyshev             }
213696ef0282SKonstantin Aladyshev 
213713791bd5SDeepak Kodihalli             if (modeIpmiToDbus.end() != modeItr)
21388cc19362SDeepak Kodihalli             {
2139e76a61a2SKonstantin Aladyshev                 rc = setBootMode(ctx, modeItr->second);
2140bfd8fc4bSjayaprakash Mutyala                 if (rc != ipmi::ccSuccess)
21418cc19362SDeepak Kodihalli                 {
214208a080abSKonstantin Aladyshev                     return ipmi::response(rc);
214398a23840SMatthew Barth                 }
214454fa1306SMarri Devender Rao                 // If a set boot device is mapping to a boot mode, then reset
214554fa1306SMarri Devender Rao                 // the boot source D-Bus property to default.
214654fa1306SMarri Devender Rao                 // This way the ipmid code can determine which property is not
214754fa1306SMarri Devender Rao                 // at the default value
214854fa1306SMarri Devender Rao                 if (modeItr->second != Mode::Modes::Regular)
214954fa1306SMarri Devender Rao                 {
215008a080abSKonstantin Aladyshev                     rc = setBootSource(ctx, Source::Sources::Default);
215108a080abSKonstantin Aladyshev                     if (rc != ipmi::ccSuccess)
215208a080abSKonstantin Aladyshev                     {
215308a080abSKonstantin Aladyshev                         return ipmi::response(rc);
215408a080abSKonstantin Aladyshev                     }
215554fa1306SMarri Devender Rao                 }
215613791bd5SDeepak Kodihalli             }
215767c5e5d6SJia, chunhui             if ((modeIpmiToDbus.end() == modeItr) &&
215896ef0282SKonstantin Aladyshev                 (typeIpmiToDbus.end() == typeItr) &&
215967c5e5d6SJia, chunhui                 (sourceIpmiToDbus.end() == sourceItr))
216067c5e5d6SJia, chunhui             {
216167c5e5d6SJia, chunhui                 // return error if boot option is not supported
216238108d9dSVernon Mauery                 lg2::error(
2163bfd8fc4bSjayaprakash Mutyala                     "ipmiChassisSetSysBootOptions: Boot option not supported");
2164bfd8fc4bSjayaprakash Mutyala                 return ipmi::responseInvalidFieldRequest();
216567c5e5d6SJia, chunhui             }
216613791bd5SDeepak Kodihalli         }
2167a2ad2da8SPatrick Williams         catch (const sdbusplus::exception_t& e)
216813791bd5SDeepak Kodihalli         {
2169225dec85SJames Feist             objectsPtr.reset();
217013791bd5SDeepak Kodihalli             report<InternalFailure>();
217138108d9dSVernon Mauery             lg2::error("ipmiChassisSetSysBootOptions: Error in setting Boot "
2172bfd8fc4bSjayaprakash Mutyala                        "flag parameters");
2173bfd8fc4bSjayaprakash Mutyala             return ipmi::responseUnspecifiedError();
2174fd28dd7aSRatan Gupta         }
21750b02be92SPatrick Venture     }
21767a0e5dfcSWilliam A. Kennington III     else if (types::enum_cast<BootOptionParameter>(parameterSelector) ==
21777a0e5dfcSWilliam A. Kennington III              BootOptionParameter::bootInfo)
21780b02be92SPatrick Venture     {
2179bfd8fc4bSjayaprakash Mutyala         uint8_t writeMak;
218038ffafcfSHieu Huynh         uint5_t bootInfoAck;
2181bfd8fc4bSjayaprakash Mutyala         uint3_t rsvd;
2182bfd8fc4bSjayaprakash Mutyala 
218338ffafcfSHieu Huynh         if (data.unpack(writeMak, bootInfoAck, rsvd) != 0 ||
2184bfd8fc4bSjayaprakash Mutyala             !data.fullyUnpacked())
2185bfd8fc4bSjayaprakash Mutyala         {
2186bfd8fc4bSjayaprakash Mutyala             return ipmi::responseReqDataLenInvalid();
2187bfd8fc4bSjayaprakash Mutyala         }
2188bfd8fc4bSjayaprakash Mutyala         if (rsvd)
2189bfd8fc4bSjayaprakash Mutyala         {
2190bfd8fc4bSjayaprakash Mutyala             return ipmi::responseInvalidFieldRequest();
2191bfd8fc4bSjayaprakash Mutyala         }
219238ffafcfSHieu Huynh         bootInitiatorAckData &= ~writeMak;
219338ffafcfSHieu Huynh         bootInitiatorAckData |= (writeMak & bootInfoAck);
219438108d9dSVernon Mauery         lg2::info("ipmiChassisSetSysBootOptions: bootInfo parameter set "
2195bfd8fc4bSjayaprakash Mutyala                   "successfully");
2196bfd8fc4bSjayaprakash Mutyala         data.trailingOk = true;
2197bfd8fc4bSjayaprakash Mutyala         return ipmi::responseSuccess();
21980b02be92SPatrick Venture     }
219986ac4991SChen Yugang     else if (types::enum_cast<BootOptionParameter>(parameterSelector) ==
220086ac4991SChen Yugang              BootOptionParameter::bootFlagValidClr)
220186ac4991SChen Yugang     {
220286ac4991SChen Yugang         uint5_t bootFlagValidClr;
220386ac4991SChen Yugang         uint3_t rsvd;
220486ac4991SChen Yugang 
220586ac4991SChen Yugang         if (data.unpack(bootFlagValidClr, rsvd) != 0 || !data.fullyUnpacked())
220686ac4991SChen Yugang         {
220786ac4991SChen Yugang             return ipmi::responseReqDataLenInvalid();
220886ac4991SChen Yugang         }
220986ac4991SChen Yugang         if (rsvd)
221086ac4991SChen Yugang         {
221186ac4991SChen Yugang             return ipmi::responseInvalidFieldRequest();
221286ac4991SChen Yugang         }
221386ac4991SChen Yugang         // store boot flag valid bits clear value
221486ac4991SChen Yugang         bootFlagValidBitClr = static_cast<uint8_t>(bootFlagValidClr);
221538108d9dSVernon Mauery         lg2::info(
221686ac4991SChen Yugang             "ipmiChassisSetSysBootOptions: bootFlagValidBits parameter set "
221738108d9dSVernon Mauery             "successfully to {VALUE}",
221838108d9dSVernon Mauery             "VALUE", lg2::hex, bootFlagValidBitClr);
221986ac4991SChen Yugang         return ipmi::responseSuccess();
222086ac4991SChen Yugang     }
22210b02be92SPatrick Venture     else
22220b02be92SPatrick Venture     {
2223bfd8fc4bSjayaprakash Mutyala         if ((parameterSelector >= static_cast<uint7_t>(oemParmStart)) &&
2224bfd8fc4bSjayaprakash Mutyala             (parameterSelector <= static_cast<uint7_t>(oemParmEnd)))
2225bfd8fc4bSjayaprakash Mutyala         {
22267a0e5dfcSWilliam A. Kennington III             if (types::enum_cast<BootOptionParameter>(parameterSelector) ==
22277a0e5dfcSWilliam A. Kennington III                 BootOptionParameter::opalNetworkSettings)
2228bfd8fc4bSjayaprakash Mutyala             {
2229bfd8fc4bSjayaprakash Mutyala                 ipmi::Cc ret = setHostNetworkData(data);
2230bfd8fc4bSjayaprakash Mutyala                 if (ret != ipmi::ccSuccess)
2231bfd8fc4bSjayaprakash Mutyala                 {
223238108d9dSVernon Mauery                     lg2::error("ipmiChassisSetSysBootOptions: Error in "
2233bfd8fc4bSjayaprakash Mutyala                                "setHostNetworkData");
2234bfd8fc4bSjayaprakash Mutyala                     data.trailingOk = true;
2235bfd8fc4bSjayaprakash Mutyala                     return ipmi::response(ret);
223698a23840SMatthew Barth                 }
2237bfd8fc4bSjayaprakash Mutyala                 data.trailingOk = true;
2238bfd8fc4bSjayaprakash Mutyala                 return ipmi::responseSuccess();
2239bfd8fc4bSjayaprakash Mutyala             }
2240bfd8fc4bSjayaprakash Mutyala             else
2241bfd8fc4bSjayaprakash Mutyala             {
224238108d9dSVernon Mauery                 lg2::error(
224338108d9dSVernon Mauery                     "ipmiChassisSetSysBootOptions: Unsupported param: {PARAM}",
224438108d9dSVernon Mauery                     "PARAM", lg2::hex, static_cast<uint8_t>(parameterSelector));
2245bfd8fc4bSjayaprakash Mutyala                 data.trailingOk = true;
2246bfd8fc4bSjayaprakash Mutyala                 return ipmi::responseParmNotSupported();
2247bfd8fc4bSjayaprakash Mutyala             }
2248bfd8fc4bSjayaprakash Mutyala         }
2249bfd8fc4bSjayaprakash Mutyala         data.trailingOk = true;
2250bfd8fc4bSjayaprakash Mutyala         return ipmi::responseParmNotSupported();
2251bfd8fc4bSjayaprakash Mutyala     }
2252bfd8fc4bSjayaprakash Mutyala     return ipmi::responseSuccess();
225398a23840SMatthew Barth }
225498a23840SMatthew Barth 
2255a5a76ebeSanil kumar appana /** @brief implements Get POH counter command
2256a5a76ebeSanil kumar appana  *  @parameter
2257a5a76ebeSanil kumar appana  *   -  none
2258a5a76ebeSanil kumar appana  *  @returns IPMI completion code plus response data
2259a5a76ebeSanil kumar appana  *   - minPerCount - Minutes per count
2260a5a76ebeSanil kumar appana  *   - counterReading - counter reading
2261a5a76ebeSanil kumar appana  */
2262a5a76ebeSanil kumar appana ipmi::RspType<uint8_t, // Minutes per count
2263a5a76ebeSanil kumar appana               uint32_t // Counter reading
2264a5a76ebeSanil kumar appana               >
ipmiGetPOHCounter()2265a5a76ebeSanil kumar appana     ipmiGetPOHCounter()
2266a59d83f8SNagaraju Goruganti {
2267a59d83f8SNagaraju Goruganti     // sd_bus error
2268a59d83f8SNagaraju Goruganti     try
2269a59d83f8SNagaraju Goruganti     {
2270a5a76ebeSanil kumar appana         return ipmi::responseSuccess(static_cast<uint8_t>(poh::minutesPerCount),
2271a5a76ebeSanil kumar appana                                      getPOHCounter());
2272a59d83f8SNagaraju Goruganti     }
2273a2ad2da8SPatrick Williams     catch (const std::exception& e)
2274a59d83f8SNagaraju Goruganti     {
227538108d9dSVernon Mauery         lg2::error("getPOHCounter error: {ERROR}", "ERROR", e);
2276a5a76ebeSanil kumar appana         return ipmi::responseUnspecifiedError();
2277a59d83f8SNagaraju Goruganti     }
2278a59d83f8SNagaraju Goruganti }
2279a59d83f8SNagaraju Goruganti 
2280bc996a35SJason M. Bills ipmi::RspType<uint3_t, // policy support
2281bc996a35SJason M. Bills               uint5_t  // reserved
2282bc996a35SJason M. Bills               >
ipmiChassisSetPowerRestorePolicy(boost::asio::yield_context yield,uint3_t policy,uint5_t reserved)2283e278ead0SVernon Mauery     ipmiChassisSetPowerRestorePolicy(boost::asio::yield_context yield,
2284bc996a35SJason M. Bills                                      uint3_t policy, uint5_t reserved)
2285c6713cffSYong Li {
2286c6713cffSYong Li     power_policy::DbusValue value =
2287c6713cffSYong Li         power_policy::RestorePolicy::Policy::AlwaysOff;
2288c6713cffSYong Li 
2289bc996a35SJason M. Bills     if (reserved || (policy > power_policy::noChange))
2290c6713cffSYong Li     {
229138108d9dSVernon Mauery         lg2::error("Reserved request parameter: {REQ}", "REQ", lg2::hex,
229238108d9dSVernon Mauery                    static_cast<int>(policy));
2293bc996a35SJason M. Bills         return ipmi::responseInvalidFieldRequest();
2294c6713cffSYong Li     }
2295c6713cffSYong Li 
2296e278ead0SVernon Mauery     if (policy == power_policy::noChange)
2297c6713cffSYong Li     {
2298c6713cffSYong Li         // just return the supported policy
2299bc996a35SJason M. Bills         return ipmi::responseSuccess(power_policy::allSupport, reserved);
2300c6713cffSYong Li     }
2301c6713cffSYong Li 
2302fbc6c9d7SPatrick Williams     for (const auto& it : power_policy::dbusToIpmi)
2303c6713cffSYong Li     {
2304e278ead0SVernon Mauery         if (it.second == policy)
2305c6713cffSYong Li         {
2306c6713cffSYong Li             value = it.first;
2307c6713cffSYong Li             break;
2308c6713cffSYong Li         }
2309c6713cffSYong Li     }
2310c6713cffSYong Li 
2311c6713cffSYong Li     try
2312c6713cffSYong Li     {
2313225dec85SJames Feist         settings::Objects& objects = chassis::internal::cache::getObjects();
2314c6713cffSYong Li         const settings::Path& powerRestoreSetting =
2315225dec85SJames Feist             objects.map.at(chassis::internal::powerRestoreIntf).front();
231616b8693dSVernon Mauery         std::variant<std::string> property = convertForMessage(value);
2317c6713cffSYong Li 
2318e278ead0SVernon Mauery         auto sdbusp = getSdBus();
2319e278ead0SVernon Mauery         boost::system::error_code ec;
2320e278ead0SVernon Mauery         sdbusp->yield_method_call<void>(
2321e278ead0SVernon Mauery             yield, ec,
2322225dec85SJames Feist             objects
2323c6713cffSYong Li                 .service(powerRestoreSetting,
2324c6713cffSYong Li                          chassis::internal::powerRestoreIntf)
2325c6713cffSYong Li                 .c_str(),
2326e278ead0SVernon Mauery             powerRestoreSetting, ipmi::PROP_INTF, "Set",
2327e278ead0SVernon Mauery             chassis::internal::powerRestoreIntf, "PowerRestorePolicy",
2328c6713cffSYong Li             property);
2329e278ead0SVernon Mauery         if (ec)
2330c6713cffSYong Li         {
233138108d9dSVernon Mauery             lg2::error("Unspecified Error");
2332e278ead0SVernon Mauery             return ipmi::responseUnspecifiedError();
2333c6713cffSYong Li         }
2334c6713cffSYong Li     }
2335a2ad2da8SPatrick Williams     catch (const InternalFailure& e)
2336c6713cffSYong Li     {
2337225dec85SJames Feist         chassis::internal::cache::objectsPtr.reset();
2338c6713cffSYong Li         report<InternalFailure>();
2339e278ead0SVernon Mauery         return ipmi::responseUnspecifiedError();
2340c6713cffSYong Li     }
2341c6713cffSYong Li 
2342bc996a35SJason M. Bills     return ipmi::responseSuccess(power_policy::allSupport, reserved);
2343c6713cffSYong Li }
2344c6713cffSYong Li 
ipmiSetFrontPanelButtonEnables(ipmi::Context::ptr ctx,bool disablePowerButton,bool disableResetButton,bool,bool,uint4_t)23451318a5edSPatrick Williams ipmi::RspType<> ipmiSetFrontPanelButtonEnables(
23461318a5edSPatrick Williams     ipmi::Context::ptr ctx, bool disablePowerButton, bool disableResetButton,
23471318a5edSPatrick Williams     bool, bool, uint4_t)
234821addc57SKuiying Wang {
234921addc57SKuiying Wang     using namespace chassis::internal;
235021addc57SKuiying Wang 
235121addc57SKuiying Wang     // set power button Enabled property
235221addc57SKuiying Wang     bool success = setButtonEnabled(ctx, powerButtonPath, powerButtonIntf,
235321addc57SKuiying Wang                                     !disablePowerButton);
235421addc57SKuiying Wang 
235521addc57SKuiying Wang     // set reset button Enabled property
235621addc57SKuiying Wang     success &= setButtonEnabled(ctx, resetButtonPath, resetButtonIntf,
235721addc57SKuiying Wang                                 !disableResetButton);
235821addc57SKuiying Wang 
235921addc57SKuiying Wang     if (!success)
236021addc57SKuiying Wang     {
236121addc57SKuiying Wang         // not all buttons were successfully set
236221addc57SKuiying Wang         return ipmi::responseUnspecifiedError();
236321addc57SKuiying Wang     }
236421addc57SKuiying Wang     return ipmi::responseSuccess();
236521addc57SKuiying Wang }
236621addc57SKuiying Wang 
registerNetFnChassisFunctions()23675087b075SGeorge Liu void registerNetFnChassisFunctions()
236898a23840SMatthew Barth {
23696706c1ccSMarri Devender Rao     createIdentifyTimer();
23706706c1ccSMarri Devender Rao 
23710573237fSTom     // Get Chassis Capabilities
237243263c60Sanil kumar appana     ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
237343263c60Sanil kumar appana                           ipmi::chassis::cmdGetChassisCapabilities,
237443263c60Sanil kumar appana                           ipmi::Privilege::User, ipmiGetChassisCap);
23758d15fb49SNan Li 
237621addc57SKuiying Wang     // Set Front Panel Button Enables
237721addc57SKuiying Wang     ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
237821addc57SKuiying Wang                           ipmi::chassis::cmdSetFrontPanelButtonEnables,
237921addc57SKuiying Wang                           ipmi::Privilege::Admin,
238021addc57SKuiying Wang                           ipmiSetFrontPanelButtonEnables);
238121addc57SKuiying Wang 
2382ae4b040bSYong Li     // Set Chassis Capabilities
2383894d0220Sanil kumar appana     ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
2384894d0220Sanil kumar appana                           ipmi::chassis::cmdSetChassisCapabilities,
2385894d0220Sanil kumar appana                           ipmi::Privilege::User, ipmiSetChassisCap);
2386ae4b040bSYong Li 
23870573237fSTom     // <Get System Boot Options>
2388d1ef877fSJayaprakash Mutyala     ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
2389d1ef877fSJayaprakash Mutyala                           ipmi::chassis::cmdGetSystemBootOptions,
2390d1ef877fSJayaprakash Mutyala                           ipmi::Privilege::Operator,
2391d1ef877fSJayaprakash Mutyala                           ipmiChassisGetSysBootOptions);
239298a23840SMatthew Barth 
23930573237fSTom     // <Get Chassis Status>
23944a8a4eb9SVernon Mauery     ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
23954a8a4eb9SVernon Mauery                           ipmi::chassis::cmdGetChassisStatus,
23964a8a4eb9SVernon Mauery                           ipmi::Privilege::User, ipmiGetChassisStatus);
2397fdd8ec55SNan Li 
2398074f64d4SVijay Khemka     // <Chassis Get System Restart Cause>
2399074f64d4SVijay Khemka     ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
2400074f64d4SVijay Khemka                           ipmi::chassis::cmdGetSystemRestartCause,
2401074f64d4SVijay Khemka                           ipmi::Privilege::User, ipmiGetSystemRestartCause);
2402074f64d4SVijay Khemka 
24030573237fSTom     // <Chassis Control>
2404dafff5f4Sanil kumar appana     ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
2405dafff5f4Sanil kumar appana                           ipmi::chassis::cmdChassisControl,
2406dafff5f4Sanil kumar appana                           ipmi::Privilege::Operator, ipmiChassisControl);
240798a23840SMatthew Barth 
24085110c125STom Joseph     // <Chassis Identify>
2409400cc789SVernon Mauery     ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
2410400cc789SVernon Mauery                           ipmi::chassis::cmdChassisIdentify,
2411400cc789SVernon Mauery                           ipmi::Privilege::Operator, ipmiChassisIdentify);
24125110c125STom Joseph 
24130573237fSTom     // <Set System Boot Options>
2414bfd8fc4bSjayaprakash Mutyala     ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
2415bfd8fc4bSjayaprakash Mutyala                           ipmi::chassis::cmdSetSystemBootOptions,
2416bfd8fc4bSjayaprakash Mutyala                           ipmi::Privilege::Operator,
2417bfd8fc4bSjayaprakash Mutyala                           ipmiChassisSetSysBootOptions);
2418bfd8fc4bSjayaprakash Mutyala 
2419a59d83f8SNagaraju Goruganti     // <Get POH Counter>
2420a5a76ebeSanil kumar appana     ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
2421a5a76ebeSanil kumar appana                           ipmi::chassis::cmdGetPohCounter,
2422a5a76ebeSanil kumar appana                           ipmi::Privilege::User, ipmiGetPOHCounter);
2423c6713cffSYong Li 
2424c6713cffSYong Li     // <Set Power Restore Policy>
2425e278ead0SVernon Mauery     ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis,
2426e278ead0SVernon Mauery                           ipmi::chassis::cmdSetPowerRestorePolicy,
2427e278ead0SVernon Mauery                           ipmi::Privilege::Operator,
2428e278ead0SVernon Mauery                           ipmiChassisSetPowerRestorePolicy);
242998a23840SMatthew Barth }
2430