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 
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/";
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 SpecialMode : uint8_t
74 {
75     none = 0,
76     mfg = 1,
77 #ifdef BMC_VALIDATION_UNSECURE_FEATURE
78     valUnsecure = 2
79 #endif
80 };
81 
82 enum class SmActionGet : uint8_t
83 {
84     sample = 0,
85     ignore = 1,
86     revert = 2
87 };
88 
89 enum class SmActionSet : uint8_t
90 {
91     forceDeasserted = 0,
92     forceAsserted = 1,
93     revert = 2
94 };
95 
96 enum class SmSignalGet : uint8_t
97 {
98     smPowerButton = 0,
99     smResetButton = 1,
100     smSleepButton,
101     smNMIButton = 3,
102     smChassisIntrusion = 4,
103     smPowerGood,
104     smPowerRequestGet,
105     smSleepRequestGet,
106     smFrbTimerHaltGet,
107     smForceUpdate,
108     smRingIndication,
109     smCarrierDetect,
110     smIdentifyButton = 0xc,
111     smFanPwmGet = 0xd,
112     smSignalReserved,
113     smFanTachometerGet = 0xf,
114     smNcsiDiag = 0x10,
115     smGetSignalMax
116 };
117 
118 enum class SmSignalSet : uint8_t
119 {
120     smPowerLed = 0,
121     smPowerFaultLed,
122     smClusterLed,
123     smDiskFaultLed,
124     smCoolingFaultLed,
125     smFanPowerSpeed = 5,
126     smPowerRequestSet,
127     smSleepRequestSet,
128     smAcpiSci,
129     smSpeaker,
130     smFanPackFaultLed,
131     smCpuFailLed,
132     smDimmFailLed,
133     smIdentifyLed,
134     smHddLed,
135     smSystemReadyLed,
136     smLcdBacklight = 0x10,
137     smSetSignalMax
138 };
139 
140 /** @enum IntrusionStatus
141 .*
142  *  Intrusion Status
143  */
144 enum class IntrusionStatus : uint8_t
145 {
146     normal = 0,
147     hardwareIntrusion,
148     tamperingDetected
149 };
150 
151 enum SupportedFeatureControls : uint8_t
152 {
153     mctp = 0,
154     pcieScan,
155 };
156 
157 enum SupportedFeatureActions : uint8_t
158 {
159     stop = 0,
160     start,
161     disable,
162     enable,
163 };
164 
165 enum SupportedMCTPBindings : uint8_t
166 {
167     mctpPCIe = 0,
168     mctpSMBusHSBP,
169     mctpSMBusPCIeSlot
170 };
171 
172 struct SetSmSignalReq
173 {
174     SmSignalSet Signal;
175     uint8_t Instance;
176     SmActionSet Action;
177     uint8_t Value;
178 };
179 
180 class LedProperty
181 {
182     SmSignalSet signal;
183     std::string name;
184     std::string prevState;
185     std::string currentState;
186     bool isLocked;
187 
188   public:
189     LedProperty(SmSignalSet signal_, std::string name_) :
190         signal(signal_), name(name_), prevState(""), isLocked(false)
191     {}
192 
193     LedProperty() = delete;
194 
195     SmSignalSet getSignal() const
196     {
197         return signal;
198     }
199 
200     void setLock(const bool& lock)
201     {
202         isLocked = lock;
203     }
204     void setPrevState(const std::string& state)
205     {
206         prevState = state;
207     }
208     void setCurrState(const std::string& state)
209     {
210         currentState = state;
211     }
212     std::string getCurrState() const
213     {
214         return currentState;
215     }
216     bool getLock() const
217     {
218         return isLocked;
219     }
220     std::string getPrevState() const
221     {
222         return prevState;
223     }
224     std::string getName() const
225     {
226         return name;
227     }
228 };
229 
230 /** @class Manufacturing
231  *
232  *  @brief Implemet commands to support Manufacturing Test Mode.
233  */
234 class Manufacturing
235 {
236     std::string path;
237     std::string gpioPaths[(uint8_t)SmSignalGet::smGetSignalMax];
238     std::vector<LedProperty> ledPropertyList;
239     void initData();
240 
241   public:
242     Manufacturing();
243 
244     ipmi_return_codes detectAccessLvl(ipmi_request_t request,
245                                       ipmi_data_len_t req_len);
246 
247     LedProperty* findLedProperty(const SmSignalSet& signal)
248     {
249         auto it = std::find_if(ledPropertyList.begin(), ledPropertyList.end(),
250                                [&signal](const LedProperty& led) {
251                                    return led.getSignal() == signal;
252                                });
253         if (it != ledPropertyList.end())
254         {
255             return &(*it);
256         }
257         return nullptr;
258     }
259 
260     std::string getLedPropertyName(const SmSignalSet signal)
261     {
262         LedProperty* led = findLedProperty(signal);
263         if (led != nullptr)
264         {
265             return led->getName();
266         }
267         else
268         {
269             return "";
270         }
271     }
272 
273     int8_t getProperty(const std::string& service, const std::string& path,
274                        const std::string& interface,
275                        const std::string& propertyName, ipmi::Value* value);
276     int8_t setProperty(const std::string& service, const std::string& path,
277                        const std::string& interface,
278                        const std::string& propertyName, ipmi::Value value);
279     int8_t disablePidControlService(const bool disable);
280 
281     void revertTimerHandler();
282 
283     SpecialMode getMfgMode(void)
284     {
285         ipmi::Value mode;
286         if (getProperty(specialModeService, specialModeObjPath, specialModeIntf,
287                         "SpecialMode", &mode) != 0)
288         {
289             return SpecialMode::none;
290         }
291         if (std::get<std::string>(mode) ==
292             "xyz.openbmc_project.Control.Security.SpecialMode.Modes."
293             "Manufacturing")
294         {
295             return SpecialMode::mfg;
296         }
297 #ifdef BMC_VALIDATION_UNSECURE_FEATURE
298         if (std::get<std::string>(mode) ==
299             "xyz.openbmc_project.Control.Security.SpecialMode.Modes."
300             "ValidationUnsecure")
301         {
302             return SpecialMode::valUnsecure;
303         }
304 #endif
305         return SpecialMode::none;
306     }
307 
308     bool revertFanPWM = false;
309     bool revertLedCallback = false;
310     phosphor::Timer revertTimer;
311     int mtmTestBeepFd = -1;
312 };
313 
314 } // namespace ipmi
315