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