blob: 5dcac09eb9225e6c23512c94c98a113904f94f11 [file] [log] [blame]
Patrick Venture391b8b02018-03-08 08:31:13 -08001/**
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
Patrick Venture36ab6f62020-08-03 10:50:26 -070017#include "manualcmds.hpp"
18
Patrick Ventured82d0b72020-08-16 09:17:37 -070019#include "dbus_mode.hpp"
Patrick Venture9bf5cef2020-08-16 08:59:54 -070020#include "manual_messages.hpp"
21
William A. Kennington III331143c2019-02-07 15:52:44 -080022#include <ipmid/api.h>
Patrick Venture391b8b02018-03-08 08:31:13 -080023
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070024#include <sdbusplus/bus.hpp>
25#include <sdbusplus/message.hpp>
Patrick Venturea83a3ec2020-08-04 09:52:05 -070026
27#include <map>
Patrick Venture391b8b02018-03-08 08:31:13 -080028#include <string>
29#include <tuple>
James Feist1f802f52019-02-08 13:51:43 -080030#include <variant>
Patrick Venture391b8b02018-03-08 08:31:13 -080031
Patrick Venture36ab6f62020-08-03 10:50:26 -070032namespace pid_control
Patrick Venture391b8b02018-03-08 08:31:13 -080033{
Patrick Venture36ab6f62020-08-03 10:50:26 -070034namespace ipmi
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070035{
Patrick Venture391b8b02018-03-08 08:31:13 -080036
37static constexpr auto objectPath = "/xyz/openbmc_project/settings/fanctrl/zone";
38static constexpr auto busName = "xyz.openbmc_project.State.FanCtrl";
Patrick Venturedc3b7902018-03-24 10:41:19 -070039static constexpr auto intf = "xyz.openbmc_project.Control.Mode";
Patrick Venture391b8b02018-03-08 08:31:13 -080040static constexpr auto manualProperty = "Manual";
41static constexpr auto failsafeProperty = "FailSafe";
42static constexpr auto propertiesintf = "org.freedesktop.DBus.Properties";
43
44using Property = std::string;
William A. Kennington III323f1d92020-06-03 11:18:24 -070045using Value = std::variant<bool>;
Patrick Venture391b8b02018-03-08 08:31:13 -080046using PropertyMap = std::map<Property, Value>;
47
48/* The following was copied directly from my manual thread handler. */
Patrick Venture7af157b2018-10-30 11:24:40 -070049static std::string getControlPath(int8_t zone)
Patrick Venture391b8b02018-03-08 08:31:13 -080050{
51 return std::string(objectPath) + std::to_string(zone);
52}
53
Patrick Venture7af157b2018-10-30 11:24:40 -070054static ipmi_ret_t getFailsafeModeState(const uint8_t* reqBuf, uint8_t* replyBuf,
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070055 size_t* dataLen)
Patrick Venture391b8b02018-03-08 08:31:13 -080056{
Patrick Venture391b8b02018-03-08 08:31:13 -080057 bool current;
58
59 if (*dataLen < sizeof(struct FanCtrlRequest))
60 {
61 return IPMI_CC_INVALID;
62 }
63
64 const auto request =
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070065 reinterpret_cast<const struct FanCtrlRequest*>(&reqBuf[0]);
Patrick Venture391b8b02018-03-08 08:31:13 -080066
Patrick Venture37b247a2020-08-03 11:15:21 -070067 ipmi_ret_t rc =
68 getFanCtrlProperty(request->zone, &current, failsafeProperty);
Patrick Venture391b8b02018-03-08 08:31:13 -080069 if (rc)
70 {
71 return rc;
72 }
73
74 *replyBuf = (uint8_t)current;
75 *dataLen = sizeof(uint8_t);
Patrick Venture37b247a2020-08-03 11:15:21 -070076 return IPMI_CC_OK;
Patrick Venture391b8b02018-03-08 08:31:13 -080077}
78
79/*
80 * <method name="GetAll">
81 * <arg name="interface" direction="in" type="s"/>
82 * <arg name="properties" direction="out" type="a{sv}"/>
83 * </method>
84 */
Patrick Venture7af157b2018-10-30 11:24:40 -070085static ipmi_ret_t getManualModeState(const uint8_t* reqBuf, uint8_t* replyBuf,
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070086 size_t* dataLen)
Patrick Venture391b8b02018-03-08 08:31:13 -080087{
Patrick Venture391b8b02018-03-08 08:31:13 -080088 bool current;
89
90 if (*dataLen < sizeof(struct FanCtrlRequest))
91 {
92 return IPMI_CC_INVALID;
93 }
94
95 const auto request =
Patrick Ventureda4a5dd2018-08-31 09:42:48 -070096 reinterpret_cast<const struct FanCtrlRequest*>(&reqBuf[0]);
Patrick Venture391b8b02018-03-08 08:31:13 -080097
Patrick Venture37b247a2020-08-03 11:15:21 -070098 ipmi_ret_t rc = getFanCtrlProperty(request->zone, &current, manualProperty);
Patrick Venture391b8b02018-03-08 08:31:13 -080099 if (rc)
100 {
101 return rc;
102 }
103
104 *replyBuf = (uint8_t)current;
105 *dataLen = sizeof(uint8_t);
Patrick Venture37b247a2020-08-03 11:15:21 -0700106 return IPMI_CC_OK;
Patrick Venture391b8b02018-03-08 08:31:13 -0800107}
108
109/*
110 * <method name="Set">
111 * <arg name="interface" direction="in" type="s"/>
112 * <arg name="property" direction="in" type="s"/>
113 * <arg name="value" direction="in" type="v"/>
114 * </method>
115 */
Patrick Venture7af157b2018-10-30 11:24:40 -0700116static ipmi_ret_t setManualModeState(const uint8_t* reqBuf, uint8_t* replyBuf,
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700117 size_t* dataLen)
Patrick Venture391b8b02018-03-08 08:31:13 -0800118{
Patrick Venture391b8b02018-03-08 08:31:13 -0800119 if (*dataLen < sizeof(struct FanCtrlRequestSet))
120 {
121 return IPMI_CC_INVALID;
122 }
123
William A. Kennington III323f1d92020-06-03 11:18:24 -0700124 using Value = std::variant<bool>;
Patrick Venture391b8b02018-03-08 08:31:13 -0800125
126 const auto request =
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700127 reinterpret_cast<const struct FanCtrlRequestSet*>(&reqBuf[0]);
Patrick Venture391b8b02018-03-08 08:31:13 -0800128
129 /* 0 is false, 1 is true */
130 bool setValue = static_cast<bool>(request->value);
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700131 Value v{setValue};
Patrick Venture391b8b02018-03-08 08:31:13 -0800132
James Feist9fa90c12019-01-11 15:35:22 -0800133 auto PropertyWriteBus = sdbusplus::bus::new_system();
Patrick Venture391b8b02018-03-08 08:31:13 -0800134
Patrick Venture7af157b2018-10-30 11:24:40 -0700135 std::string path = getControlPath(request->zone);
Patrick Venture391b8b02018-03-08 08:31:13 -0800136
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700137 auto pimMsg = PropertyWriteBus.new_method_call(busName, path.c_str(),
138 propertiesintf, "Set");
Patrick Venture391b8b02018-03-08 08:31:13 -0800139 pimMsg.append(intf);
140 pimMsg.append(manualProperty);
141 pimMsg.append(v);
Patrick Ventureacecf6b2018-09-06 17:56:41 -0700142
Patrick Venture37b247a2020-08-03 11:15:21 -0700143 ipmi_ret_t rc = IPMI_CC_OK;
144
Patrick Ventureacecf6b2018-09-06 17:56:41 -0700145 try
146 {
147 PropertyWriteBus.call_noreply(pimMsg);
148 }
149 catch (const sdbusplus::exception::SdBusError& ex)
Patrick Venture391b8b02018-03-08 08:31:13 -0800150 {
151 rc = IPMI_CC_INVALID;
152 }
153 /* TODO(venture): Should sanity check the result. */
154
155 return rc;
156}
157
158/* Three command packages: get, set true, set false */
Patrick Venture9bf5cef2020-08-16 08:59:54 -0700159ipmi_ret_t manualModeControl(ipmi_cmd_t cmd, const uint8_t* reqBuf,
160 uint8_t* replyCmdBuf, size_t* dataLen)
Patrick Venture391b8b02018-03-08 08:31:13 -0800161{
Patrick Venture391b8b02018-03-08 08:31:13 -0800162 // FanCtrlRequest is the smaller of the requests, so it's at a minimum.
163 if (*dataLen < sizeof(struct FanCtrlRequest))
164 {
165 return IPMI_CC_INVALID;
166 }
167
168 const auto request =
Patrick Ventureda4a5dd2018-08-31 09:42:48 -0700169 reinterpret_cast<const struct FanCtrlRequest*>(&reqBuf[0]);
Patrick Venture391b8b02018-03-08 08:31:13 -0800170
Patrick Venture37b247a2020-08-03 11:15:21 -0700171 ipmi_ret_t rc = IPMI_CC_OK;
172
Patrick Venture391b8b02018-03-08 08:31:13 -0800173 switch (request->command)
174 {
Patrick Venture12775432020-08-04 09:57:36 -0700175 case getControlState:
Patrick Venture7af157b2018-10-30 11:24:40 -0700176 return getManualModeState(reqBuf, replyCmdBuf, dataLen);
Patrick Venture12775432020-08-04 09:57:36 -0700177 case setControlState:
Patrick Venture7af157b2018-10-30 11:24:40 -0700178 return setManualModeState(reqBuf, replyCmdBuf, dataLen);
Patrick Venture12775432020-08-04 09:57:36 -0700179 case getFailsafeState:
Patrick Venture7af157b2018-10-30 11:24:40 -0700180 return getFailsafeModeState(reqBuf, replyCmdBuf, dataLen);
Patrick Venture391b8b02018-03-08 08:31:13 -0800181 default:
182 rc = IPMI_CC_INVALID;
183 }
184
185 return rc;
186}
187
Patrick Venture36ab6f62020-08-03 10:50:26 -0700188} // namespace ipmi
189} // namespace pid_control