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