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