xref: /openbmc/phosphor-pid-control/ipmi/manualcmds.cpp (revision 46a755fce8dc0bdd9c0c5ea09d55d3e5494f335f)
1 // SPDX-License-Identifier: Apache-2.0
2 // SPDX-FileCopyrightText: Copyright 2017 Google Inc
3 
4 #include "manualcmds.hpp"
5 
6 #include "control.hpp"
7 #include "manual_messages.hpp"
8 
9 #include <ipmid/api-types.hpp>
10 
11 #include <cstddef>
12 #include <cstdint>
13 #include <memory>
14 #include <string>
15 
16 namespace pid_control::ipmi
17 {
18 
19 static constexpr auto manualProperty = "Manual";
20 static constexpr auto failsafeProperty = "FailSafe";
21 
getFailsafeModeState(const uint8_t * reqBuf,uint8_t * replyBuf,size_t * dataLen)22 ::ipmi::Cc ZoneControlIpmiHandler::getFailsafeModeState(
23     const uint8_t* reqBuf, uint8_t* replyBuf, size_t* dataLen)
24 {
25     bool current;
26 
27     if (*dataLen < sizeof(struct FanCtrlRequest))
28     {
29         return ::ipmi::ccInvalidCommand;
30     }
31 
32     const auto request =
33         reinterpret_cast<const struct FanCtrlRequest*>(&reqBuf[0]);
34 
35     ::ipmi::Cc rc =
36         _control->getFanCtrlProperty(request->zone, &current, failsafeProperty);
37     if (rc)
38     {
39         return rc;
40     }
41 
42     *replyBuf = (uint8_t)current;
43     *dataLen = sizeof(uint8_t);
44     return ::ipmi::ccSuccess;
45 }
46 
47 /*
48  * <method name="GetAll">
49  *   <arg name="interface" direction="in" type="s"/>
50  *   <arg name="properties" direction="out" type="a{sv}"/>
51  * </method>
52  */
getManualModeState(const uint8_t * reqBuf,uint8_t * replyBuf,size_t * dataLen)53 ::ipmi::Cc ZoneControlIpmiHandler::getManualModeState(
54     const uint8_t* reqBuf, uint8_t* replyBuf, size_t* dataLen)
55 {
56     bool current;
57 
58     if (*dataLen < sizeof(struct FanCtrlRequest))
59     {
60         return ::ipmi::ccInvalidCommand;
61     }
62 
63     const auto request =
64         reinterpret_cast<const struct FanCtrlRequest*>(&reqBuf[0]);
65 
66     ::ipmi::Cc rc =
67         _control->getFanCtrlProperty(request->zone, &current, manualProperty);
68     if (rc)
69     {
70         return rc;
71     }
72 
73     *replyBuf = (uint8_t)current;
74     *dataLen = sizeof(uint8_t);
75     return ::ipmi::ccSuccess;
76 }
77 
78 /*
79  * <method name="Set">
80  *   <arg name="interface" direction="in" type="s"/>
81  *   <arg name="property" direction="in" type="s"/>
82  *   <arg name="value" direction="in" type="v"/>
83  * </method>
84  */
setManualModeState(const uint8_t * reqBuf,uint8_t * replyBuf,const size_t * dataLen)85 ::ipmi::Cc ZoneControlIpmiHandler::setManualModeState(
86     const uint8_t* reqBuf, [[maybe_unused]] uint8_t* replyBuf,
87     const size_t* dataLen)
88 {
89     if (*dataLen < sizeof(struct FanCtrlRequestSet))
90     {
91         return ::ipmi::ccInvalidCommand;
92     }
93 
94     const auto request =
95         reinterpret_cast<const struct FanCtrlRequestSet*>(&reqBuf[0]);
96 
97     /* 0 is false, 1 is true */
98     ::ipmi::Cc rc = _control->setFanCtrlProperty(
99         request->zone, static_cast<bool>(request->value), manualProperty);
100     return rc;
101 }
102 
103 /* Three command packages: get, set true, set false */
manualModeControl(ZoneControlIpmiHandler * handler,uint8_t cmd,const uint8_t * reqBuf,uint8_t * replyCmdBuf,size_t * dataLen)104 ::ipmi::Cc manualModeControl(
105     ZoneControlIpmiHandler* handler, [[maybe_unused]] uint8_t cmd,
106     const uint8_t* reqBuf, uint8_t* replyCmdBuf, size_t* dataLen)
107 {
108     // FanCtrlRequest is the smaller of the requests, so it's at a minimum.
109     if (*dataLen < sizeof(struct FanCtrlRequest))
110     {
111         return ::ipmi::ccInvalidCommand;
112     }
113 
114     const auto request =
115         reinterpret_cast<const struct FanCtrlRequest*>(&reqBuf[0]);
116 
117     ::ipmi::Cc rc = ::ipmi::ccSuccess;
118 
119     switch (request->command)
120     {
121         case getControlState:
122             return handler->getManualModeState(reqBuf, replyCmdBuf, dataLen);
123         case setControlState:
124             return handler->setManualModeState(reqBuf, replyCmdBuf, dataLen);
125         case getFailsafeState:
126             return handler->getFailsafeModeState(reqBuf, replyCmdBuf, dataLen);
127         default:
128             rc = ::ipmi::ccInvalidCommand;
129     }
130 
131     return rc;
132 }
133 
134 } // namespace pid_control::ipmi
135