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