xref: /openbmc/phosphor-pid-control/ipmi/manualcmds.cpp (revision f8b6e55147148c3cfb42327ff267197a460b411c)
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 "manual_messages.hpp"
21 
22 #include <ipmid/api.h>
23 
24 #include <cstddef>
25 #include <cstdint>
26 #include <memory>
27 #include <string>
28 
29 namespace pid_control
30 {
31 namespace ipmi
32 {
33 
34 static constexpr auto manualProperty = "Manual";
35 static constexpr auto failsafeProperty = "FailSafe";
36 
37 ipmi_ret_t ZoneControlIpmiHandler::getFailsafeModeState(
38     const uint8_t* reqBuf, uint8_t* replyBuf, size_t* dataLen)
39 {
40     bool current;
41 
42     if (*dataLen < sizeof(struct FanCtrlRequest))
43     {
44         return IPMI_CC_INVALID;
45     }
46 
47     const auto request =
48         reinterpret_cast<const struct FanCtrlRequest*>(&reqBuf[0]);
49 
50     ipmi_ret_t rc =
51         _control->getFanCtrlProperty(request->zone, &current, failsafeProperty);
52     if (rc)
53     {
54         return rc;
55     }
56 
57     *replyBuf = (uint8_t)current;
58     *dataLen = sizeof(uint8_t);
59     return IPMI_CC_OK;
60 }
61 
62 /*
63  * <method name="GetAll">
64  *   <arg name="interface" direction="in" type="s"/>
65  *   <arg name="properties" direction="out" type="a{sv}"/>
66  * </method>
67  */
68 ipmi_ret_t ZoneControlIpmiHandler::getManualModeState(
69     const uint8_t* reqBuf, uint8_t* replyBuf, size_t* dataLen)
70 {
71     bool current;
72 
73     if (*dataLen < sizeof(struct FanCtrlRequest))
74     {
75         return IPMI_CC_INVALID;
76     }
77 
78     const auto request =
79         reinterpret_cast<const struct FanCtrlRequest*>(&reqBuf[0]);
80 
81     ipmi_ret_t rc =
82         _control->getFanCtrlProperty(request->zone, &current, manualProperty);
83     if (rc)
84     {
85         return rc;
86     }
87 
88     *replyBuf = (uint8_t)current;
89     *dataLen = sizeof(uint8_t);
90     return IPMI_CC_OK;
91 }
92 
93 /*
94  * <method name="Set">
95  *   <arg name="interface" direction="in" type="s"/>
96  *   <arg name="property" direction="in" type="s"/>
97  *   <arg name="value" direction="in" type="v"/>
98  * </method>
99  */
100 ipmi_ret_t ZoneControlIpmiHandler::setManualModeState(
101     const uint8_t* reqBuf, [[maybe_unused]] uint8_t* replyBuf,
102     const size_t* dataLen)
103 {
104     if (*dataLen < sizeof(struct FanCtrlRequestSet))
105     {
106         return IPMI_CC_INVALID;
107     }
108 
109     const auto request =
110         reinterpret_cast<const struct FanCtrlRequestSet*>(&reqBuf[0]);
111 
112     /* 0 is false, 1 is true */
113     ipmi_ret_t rc = _control->setFanCtrlProperty(
114         request->zone, static_cast<bool>(request->value), manualProperty);
115     return rc;
116 }
117 
118 /* Three command packages: get, set true, set false */
119 ipmi_ret_t manualModeControl(
120     ZoneControlIpmiHandler* handler, [[maybe_unused]] ipmi_cmd_t cmd,
121     const uint8_t* reqBuf, uint8_t* replyCmdBuf, size_t* dataLen)
122 {
123     // FanCtrlRequest is the smaller of the requests, so it's at a minimum.
124     if (*dataLen < sizeof(struct FanCtrlRequest))
125     {
126         return IPMI_CC_INVALID;
127     }
128 
129     const auto request =
130         reinterpret_cast<const struct FanCtrlRequest*>(&reqBuf[0]);
131 
132     ipmi_ret_t rc = IPMI_CC_OK;
133 
134     switch (request->command)
135     {
136         case getControlState:
137             return handler->getManualModeState(reqBuf, replyCmdBuf, dataLen);
138         case setControlState:
139             return handler->setManualModeState(reqBuf, replyCmdBuf, dataLen);
140         case getFailsafeState:
141             return handler->getFailsafeModeState(reqBuf, replyCmdBuf, dataLen);
142         default:
143             rc = IPMI_CC_INVALID;
144     }
145 
146     return rc;
147 }
148 
149 } // namespace ipmi
150 } // namespace pid_control
151