1 /* 2 // Copyright (c) 2018 Intel Corporation 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 #pragma once 18 19 #include <ipmid/api-types.hpp> 20 #include <ipmid/utils.hpp> 21 #include <phosphor-logging/log.hpp> 22 #include <sdbusplus/bus.hpp> 23 #include <sdbusplus/message.hpp> 24 #include <sdbusplus/timer.hpp> 25 #include <variantvisitors.hpp> 26 #include <vector> 27 28 #define FAN_SENSOR_NOT_PRESENT (0 << 0) 29 #define FAN_SENSOR_PRESENT (1 << 0) 30 #define FAN_NOT_PRESENT (0 << 1) 31 #define FAN_PRESENT (1 << 1) 32 33 namespace ipmi 34 { 35 36 // TODO: Service names may change. Worth to consider dynamic detection. 37 static constexpr const char* fanService = "xyz.openbmc_project.FanSensor"; 38 static constexpr const char* buttonService = 39 "xyz.openbmc_project.Chassis.Buttons"; 40 static constexpr const char* ledServicePrefix = 41 "xyz.openbmc_project.LED.Controller."; 42 43 static constexpr const char* ledPathPrefix = 44 "/xyz/openbmc_project/led/physical/"; 45 static constexpr const char* fanPwmPath = 46 "/xyz/openbmc_project/sensors/fan_pwm/Pwm_"; 47 static constexpr const char* fanTachBasePath = 48 "/xyz/openbmc_project/sensors/fan_tach/"; 49 50 static constexpr const char* fanIntf = "xyz.openbmc_project.Sensor.Value"; 51 static constexpr const char* buttonIntf = "xyz.openbmc_project.Chassis.Buttons"; 52 static constexpr const char* ledIntf = "xyz.openbmc_project.Led.Physical"; 53 54 static constexpr const char* intrusionService = 55 "xyz.openbmc_project.IntrusionSensor"; 56 static constexpr const char* intrusionPath = 57 "/xyz/openbmc_project/Intrusion/Chassis_Intrusion"; 58 static constexpr const char* intrusionIntf = 59 "xyz.openbmc_project.Chassis.Intrusion"; 60 61 static constexpr const char* busPropertyIntf = 62 "org.freedesktop.DBus.Properties"; 63 static constexpr const char* ledStateStr = 64 "xyz.openbmc_project.Led.Physical.Action."; // Comes with postfix Off/On 65 66 static constexpr const char* specialModeService = 67 "xyz.openbmc_project.SpecialMode"; 68 static constexpr const char* specialModeObjPath = 69 "/xyz/openbmc_project/security/special_mode"; 70 static constexpr const char* specialModeIntf = 71 "xyz.openbmc_project.Security.SpecialMode"; 72 73 enum class SmActionGet : uint8_t 74 { 75 sample = 0, 76 ignore = 1, 77 revert = 2 78 }; 79 80 enum class SmActionSet : uint8_t 81 { 82 forceDeasserted = 0, 83 forceAsserted = 1, 84 revert = 2 85 }; 86 87 enum class SmSignalGet : uint8_t 88 { 89 smPowerButton = 0, 90 smResetButton = 1, 91 smSleepButton, 92 smNMIButton = 3, 93 smChassisIntrusion = 4, 94 smPowerGood, 95 smPowerRequestGet, 96 smSleepRequestGet, 97 smFrbTimerHaltGet, 98 smForceUpdate, 99 smRingIndication, 100 smCarrierDetect, 101 smIdentifyButton = 0xc, 102 smFanPwmGet = 0xd, 103 smSignalReserved, 104 smFanTachometerGet = 0xf, 105 smNcsiDiag = 0x10, 106 smGetSignalMax 107 }; 108 109 enum class SmSignalSet : uint8_t 110 { 111 smPowerLed = 0, 112 smPowerFaultLed, 113 smClusterLed, 114 smDiskFaultLed, 115 smCoolingFaultLed, 116 smFanPowerSpeed = 5, 117 smPowerRequestSet, 118 smSleepRequestSet, 119 smAcpiSci, 120 smSpeaker, 121 smFanPackFaultLed, 122 smCpuFailLed, 123 smDimmFailLed, 124 smIdentifyLed, 125 smHddLed, 126 smSystemReadyLed, 127 smLcdBacklight = 0x10, 128 smSetSignalMax 129 }; 130 131 /** @enum IntrusionStatus 132 .* 133 * Intrusion Status 134 */ 135 enum class IntrusionStatus : uint8_t 136 { 137 normal = 0, 138 hardwareIntrusion, 139 tamperingDetected 140 }; 141 142 struct SetSmSignalReq 143 { 144 SmSignalSet Signal; 145 uint8_t Instance; 146 SmActionSet Action; 147 uint8_t Value; 148 }; 149 150 class LedProperty 151 { 152 SmSignalSet signal; 153 std::string name; 154 std::string prevState; 155 std::string currentState; 156 bool isLocked; 157 158 public: 159 LedProperty(SmSignalSet signal_, std::string name_) : 160 signal(signal_), name(name_), prevState(""), isLocked(false) 161 { 162 } 163 164 LedProperty() = delete; 165 166 SmSignalSet getSignal() const 167 { 168 return signal; 169 } 170 171 void setLock(const bool& lock) 172 { 173 isLocked = lock; 174 } 175 void setPrevState(const std::string& state) 176 { 177 prevState = state; 178 } 179 void setCurrState(const std::string& state) 180 { 181 currentState = state; 182 } 183 std::string getCurrState() const 184 { 185 return currentState; 186 } 187 bool getLock() const 188 { 189 return isLocked; 190 } 191 std::string getPrevState() const 192 { 193 return prevState; 194 } 195 std::string getName() const 196 { 197 return name; 198 } 199 }; 200 201 /** @class Manufacturing 202 * 203 * @brief Implemet commands to support Manufacturing Test Mode. 204 */ 205 class Manufacturing 206 { 207 std::string path; 208 std::string gpioPaths[(uint8_t)SmSignalGet::smGetSignalMax]; 209 std::vector<LedProperty> ledPropertyList; 210 void initData(); 211 212 public: 213 Manufacturing(); 214 215 ipmi_return_codes detectAccessLvl(ipmi_request_t request, 216 ipmi_data_len_t req_len); 217 218 LedProperty* findLedProperty(const SmSignalSet& signal) 219 { 220 auto it = std::find_if(ledPropertyList.begin(), ledPropertyList.end(), 221 [&signal](const LedProperty& led) { 222 return led.getSignal() == signal; 223 }); 224 if (it != ledPropertyList.end()) 225 { 226 return &(*it); 227 } 228 return nullptr; 229 } 230 231 std::string getLedPropertyName(const SmSignalSet signal) 232 { 233 LedProperty* led = findLedProperty(signal); 234 if (led != nullptr) 235 { 236 return led->getName(); 237 } 238 else 239 { 240 return ""; 241 } 242 } 243 244 int8_t getProperty(const std::string& service, const std::string& path, 245 const std::string& interface, 246 const std::string& propertyName, ipmi::Value* value); 247 int8_t setProperty(const std::string& service, const std::string& path, 248 const std::string& interface, 249 const std::string& propertyName, ipmi::Value value); 250 int8_t disablePidControlService(const bool disable); 251 252 void revertTimerHandler(); 253 254 bool isMfgMode(void) 255 { 256 ipmi::Value mode; 257 if (getProperty(specialModeService, specialModeObjPath, specialModeIntf, 258 "SpecialMode", &mode) != 0) 259 { 260 return false; 261 } 262 if (std::get<std::string>(mode) == 263 "xyz.openbmc_project.Control.Security.SpecialMode.Modes." 264 "Manufacturing") 265 { 266 return true; 267 } 268 #ifdef BMC_VALIDATION_UNSECURE_FEATURE 269 if (std::get<std::string>(mode) == 270 "xyz.openbmc_project.Control.Security.SpecialMode.Modes." 271 "ValidationUnsecure") 272 { 273 return true; 274 } 275 #endif 276 return false; 277 } 278 279 bool revertFanPWM = false; 280 bool revertLedCallback = false; 281 phosphor::Timer revertTimer; 282 int mtmTestBeepFd = -1; 283 }; 284 285 } // namespace ipmi 286