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 enum SupportedFeatureControls : uint8_t
153 {
154     mctp = 0,
155     pcieScan,
156 };
157 
158 enum SupportedFeatureActions : uint8_t
159 {
160     stop = 0,
161     start,
162     disable,
163     enable,
164 };
165 
166 enum SupportedMCTPBindings : uint8_t
167 {
168     mctpPCIe = 0,
169     mctpSMBusHSBP,
170     mctpSMBusPCIeSlot
171 };
172 
173 struct SetSmSignalReq
174 {
175     SmSignalSet Signal;
176     uint8_t Instance;
177     SmActionSet Action;
178     uint8_t Value;
179 };
180 
181 class LedProperty
182 {
183     SmSignalSet signal;
184     std::string name;
185     std::string prevState;
186     std::string currentState;
187     bool isLocked;
188 
189   public:
190     LedProperty(SmSignalSet signal_, std::string name_) :
191         signal(signal_), name(name_), prevState(""), isLocked(false)
192     {}
193 
194     LedProperty() = delete;
195 
196     SmSignalSet getSignal() const
197     {
198         return signal;
199     }
200 
201     void setLock(const bool& lock)
202     {
203         isLocked = lock;
204     }
205     void setPrevState(const std::string& state)
206     {
207         prevState = state;
208     }
209     void setCurrState(const std::string& state)
210     {
211         currentState = state;
212     }
213     std::string getCurrState() const
214     {
215         return currentState;
216     }
217     bool getLock() const
218     {
219         return isLocked;
220     }
221     std::string getPrevState() const
222     {
223         return prevState;
224     }
225     std::string getName() const
226     {
227         return name;
228     }
229 };
230 
231 /** @class Manufacturing
232  *
233  *  @brief Implemet commands to support Manufacturing Test Mode.
234  */
235 class Manufacturing
236 {
237     std::string path;
238     std::string gpioPaths[(uint8_t)SmSignalGet::smGetSignalMax];
239     std::vector<LedProperty> ledPropertyList;
240     void initData();
241 
242   public:
243     Manufacturing();
244 
245     ipmi_return_codes detectAccessLvl(ipmi_request_t request,
246                                       ipmi_data_len_t req_len);
247 
248     LedProperty* findLedProperty(const SmSignalSet& signal)
249     {
250         auto it = std::find_if(ledPropertyList.begin(), ledPropertyList.end(),
251                                [&signal](const LedProperty& led) {
252                                    return led.getSignal() == signal;
253                                });
254         if (it != ledPropertyList.end())
255         {
256             return &(*it);
257         }
258         return nullptr;
259     }
260 
261     std::string getLedPropertyName(const SmSignalSet signal)
262     {
263         LedProperty* led = findLedProperty(signal);
264         if (led != nullptr)
265         {
266             return led->getName();
267         }
268         else
269         {
270             return "";
271         }
272     }
273 
274     int8_t getProperty(const std::string& service, const std::string& path,
275                        const std::string& interface,
276                        const std::string& propertyName, ipmi::Value* value);
277     int8_t setProperty(const std::string& service, const std::string& path,
278                        const std::string& interface,
279                        const std::string& propertyName, ipmi::Value value);
280     int8_t disablePidControlService(const bool disable);
281 
282     void revertTimerHandler();
283 
284     SpecialMode getMfgMode(void)
285     {
286         ipmi::Value mode;
287         if (getProperty(specialModeService, specialModeObjPath, specialModeIntf,
288                         "SpecialMode", &mode) != 0)
289         {
290             return SpecialMode::none;
291         }
292         if (std::get<std::string>(mode) ==
293             "xyz.openbmc_project.Control.Security.SpecialMode.Modes."
294             "Manufacturing")
295         {
296             return SpecialMode::mfg;
297         }
298 #ifdef BMC_VALIDATION_UNSECURE_FEATURE
299         if (std::get<std::string>(mode) ==
300             "xyz.openbmc_project.Control.Security.SpecialMode.Modes."
301             "ValidationUnsecure")
302         {
303             return SpecialMode::valUnsecure;
304         }
305 #endif
306         return SpecialMode::none;
307     }
308 
309     bool revertFanPWM = false;
310     bool revertLedCallback = false;
311     phosphor::Timer revertTimer;
312     int mtmTestBeepFd = -1;
313 };
314 
315 } // namespace ipmi
316