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(const uint8_t* reqBuf,
43 uint8_t* replyBuf,
44 size_t* dataLen)
45 {
46 bool current;
47
48 if (*dataLen < sizeof(struct FanCtrlRequest))
49 {
50 return IPMI_CC_INVALID;
51 }
52
53 const auto request =
54 reinterpret_cast<const struct FanCtrlRequest*>(&reqBuf[0]);
55
56 ipmi_ret_t rc = _control->getFanCtrlProperty(request->zone, ¤t,
57 failsafeProperty);
58 if (rc)
59 {
60 return rc;
61 }
62
63 *replyBuf = (uint8_t)current;
64 *dataLen = sizeof(uint8_t);
65 return IPMI_CC_OK;
66 }
67
68 /*
69 * <method name="GetAll">
70 * <arg name="interface" direction="in" type="s"/>
71 * <arg name="properties" direction="out" type="a{sv}"/>
72 * </method>
73 */
getManualModeState(const uint8_t * reqBuf,uint8_t * replyBuf,size_t * dataLen)74 ipmi_ret_t ZoneControlIpmiHandler::getManualModeState(const uint8_t* reqBuf,
75 uint8_t* replyBuf,
76 size_t* dataLen)
77 {
78 bool current;
79
80 if (*dataLen < sizeof(struct FanCtrlRequest))
81 {
82 return IPMI_CC_INVALID;
83 }
84
85 const auto request =
86 reinterpret_cast<const struct FanCtrlRequest*>(&reqBuf[0]);
87
88 ipmi_ret_t rc = _control->getFanCtrlProperty(request->zone, ¤t,
89 manualProperty);
90 if (rc)
91 {
92 return rc;
93 }
94
95 *replyBuf = (uint8_t)current;
96 *dataLen = sizeof(uint8_t);
97 return IPMI_CC_OK;
98 }
99
100 /*
101 * <method name="Set">
102 * <arg name="interface" direction="in" type="s"/>
103 * <arg name="property" direction="in" type="s"/>
104 * <arg name="value" direction="in" type="v"/>
105 * </method>
106 */
setManualModeState(const uint8_t * reqBuf,uint8_t * replyBuf,const size_t * dataLen)107 ipmi_ret_t ZoneControlIpmiHandler::setManualModeState(
108 const uint8_t* reqBuf, [[maybe_unused]] uint8_t* replyBuf,
109 const size_t* dataLen)
110 {
111 if (*dataLen < sizeof(struct FanCtrlRequestSet))
112 {
113 return IPMI_CC_INVALID;
114 }
115
116 const auto request =
117 reinterpret_cast<const struct FanCtrlRequestSet*>(&reqBuf[0]);
118
119 /* 0 is false, 1 is true */
120 ipmi_ret_t rc = _control->setFanCtrlProperty(
121 request->zone, static_cast<bool>(request->value), manualProperty);
122 return rc;
123 }
124
125 /* 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)126 ipmi_ret_t manualModeControl(ZoneControlIpmiHandler* handler,
127 [[maybe_unused]] ipmi_cmd_t cmd,
128 const uint8_t* reqBuf, uint8_t* replyCmdBuf,
129 size_t* dataLen)
130 {
131 // FanCtrlRequest is the smaller of the requests, so it's at a minimum.
132 if (*dataLen < sizeof(struct FanCtrlRequest))
133 {
134 return IPMI_CC_INVALID;
135 }
136
137 const auto request =
138 reinterpret_cast<const struct FanCtrlRequest*>(&reqBuf[0]);
139
140 ipmi_ret_t rc = IPMI_CC_OK;
141
142 switch (request->command)
143 {
144 case getControlState:
145 return handler->getManualModeState(reqBuf, replyCmdBuf, dataLen);
146 case setControlState:
147 return handler->setManualModeState(reqBuf, replyCmdBuf, dataLen);
148 case getFailsafeState:
149 return handler->getFailsafeModeState(reqBuf, replyCmdBuf, dataLen);
150 default:
151 rc = IPMI_CC_INVALID;
152 }
153
154 return rc;
155 }
156
157 } // namespace ipmi
158 } // namespace pid_control
159