xref: /openbmc/phosphor-pid-control/ipmi/manualcmds.cpp (revision bd63bcaca2ac9edf1778136cf240e3bbe8b31566)
1 /**
2  * Copyright 2017 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "manualcmds.hpp"
18 
19 #include "control.hpp"
20 #include "dbus_mode.hpp"
21 #include "manual_messages.hpp"
22 
23 #include <ipmid/api.h>
24 
25 #include <sdbusplus/bus.hpp>
26 #include <sdbusplus/message.hpp>
27 
28 #include <map>
29 #include <memory>
30 #include <string>
31 #include <tuple>
32 #include <variant>
33 
34 namespace pid_control
35 {
36 namespace ipmi
37 {
38 
39 static constexpr auto manualProperty = "Manual";
40 static constexpr auto failsafeProperty = "FailSafe";
41 
getFailsafeModeState(const uint8_t * reqBuf,uint8_t * replyBuf,size_t * dataLen)42 ipmi_ret_t ZoneControlIpmiHandler::getFailsafeModeState(
43     const uint8_t* reqBuf, uint8_t* replyBuf, size_t* dataLen)
44 {
45     bool current;
46 
47     if (*dataLen < sizeof(struct FanCtrlRequest))
48     {
49         return IPMI_CC_INVALID;
50     }
51 
52     const auto request =
53         reinterpret_cast<const struct FanCtrlRequest*>(&reqBuf[0]);
54 
55     ipmi_ret_t rc =
56         _control->getFanCtrlProperty(request->zone, &current, failsafeProperty);
57     if (rc)
58     {
59         return rc;
60     }
61 
62     *replyBuf = (uint8_t)current;
63     *dataLen = sizeof(uint8_t);
64     return IPMI_CC_OK;
65 }
66 
67 /*
68  * <method name="GetAll">
69  *   <arg name="interface" direction="in" type="s"/>
70  *   <arg name="properties" direction="out" type="a{sv}"/>
71  * </method>
72  */
getManualModeState(const uint8_t * reqBuf,uint8_t * replyBuf,size_t * dataLen)73 ipmi_ret_t ZoneControlIpmiHandler::getManualModeState(
74     const uint8_t* reqBuf, uint8_t* replyBuf, size_t* dataLen)
75 {
76     bool current;
77 
78     if (*dataLen < sizeof(struct FanCtrlRequest))
79     {
80         return IPMI_CC_INVALID;
81     }
82 
83     const auto request =
84         reinterpret_cast<const struct FanCtrlRequest*>(&reqBuf[0]);
85 
86     ipmi_ret_t rc =
87         _control->getFanCtrlProperty(request->zone, &current, manualProperty);
88     if (rc)
89     {
90         return rc;
91     }
92 
93     *replyBuf = (uint8_t)current;
94     *dataLen = sizeof(uint8_t);
95     return IPMI_CC_OK;
96 }
97 
98 /*
99  * <method name="Set">
100  *   <arg name="interface" direction="in" type="s"/>
101  *   <arg name="property" direction="in" type="s"/>
102  *   <arg name="value" direction="in" type="v"/>
103  * </method>
104  */
setManualModeState(const uint8_t * reqBuf,uint8_t * replyBuf,const size_t * dataLen)105 ipmi_ret_t ZoneControlIpmiHandler::setManualModeState(
106     const uint8_t* reqBuf, [[maybe_unused]] uint8_t* replyBuf,
107     const size_t* dataLen)
108 {
109     if (*dataLen < sizeof(struct FanCtrlRequestSet))
110     {
111         return IPMI_CC_INVALID;
112     }
113 
114     const auto request =
115         reinterpret_cast<const struct FanCtrlRequestSet*>(&reqBuf[0]);
116 
117     /* 0 is false, 1 is true */
118     ipmi_ret_t rc = _control->setFanCtrlProperty(
119         request->zone, static_cast<bool>(request->value), manualProperty);
120     return rc;
121 }
122 
123 /* Three command packages: get, set true, set false */
manualModeControl(ZoneControlIpmiHandler * handler,ipmi_cmd_t cmd,const uint8_t * reqBuf,uint8_t * replyCmdBuf,size_t * dataLen)124 ipmi_ret_t manualModeControl(
125     ZoneControlIpmiHandler* handler, [[maybe_unused]] ipmi_cmd_t cmd,
126     const uint8_t* reqBuf, uint8_t* replyCmdBuf, size_t* dataLen)
127 {
128     // FanCtrlRequest is the smaller of the requests, so it's at a minimum.
129     if (*dataLen < sizeof(struct FanCtrlRequest))
130     {
131         return IPMI_CC_INVALID;
132     }
133 
134     const auto request =
135         reinterpret_cast<const struct FanCtrlRequest*>(&reqBuf[0]);
136 
137     ipmi_ret_t rc = IPMI_CC_OK;
138 
139     switch (request->command)
140     {
141         case getControlState:
142             return handler->getManualModeState(reqBuf, replyCmdBuf, dataLen);
143         case setControlState:
144             return handler->setManualModeState(reqBuf, replyCmdBuf, dataLen);
145         case getFailsafeState:
146             return handler->getFailsafeModeState(reqBuf, replyCmdBuf, dataLen);
147         default:
148             rc = IPMI_CC_INVALID;
149     }
150 
151     return rc;
152 }
153 
154 } // namespace ipmi
155 } // namespace pid_control
156