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, ¤t, 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, ¤t, 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