1 /*
2 // Copyright (c) 2017 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 #include <cstdint>
19 #include <dbus-sdr/sdrutils.hpp>
20 
21 #pragma pack(push, 1)
22 
23 struct SensorThresholdResp
24 {
25     uint8_t readable;
26     uint8_t lowernc;
27     uint8_t lowercritical;
28     uint8_t lowernonrecoverable;
29     uint8_t uppernc;
30     uint8_t uppercritical;
31     uint8_t uppernonrecoverable;
32 };
33 
34 #pragma pack(pop)
35 
36 enum class IPMIThresholdRespBits
37 {
38     lowerNonCritical,
39     lowerCritical,
40     lowerNonRecoverable,
41     upperNonCritical,
42     upperCritical,
43     upperNonRecoverable
44 };
45 
46 enum class IPMISensorReadingByte2 : uint8_t
47 {
48     eventMessagesEnable = (1 << 7),
49     sensorScanningEnable = (1 << 6),
50     readingStateUnavailable = (1 << 5),
51 };
52 
53 enum class IPMISensorReadingByte3 : uint8_t
54 {
55     upperNonRecoverable = (1 << 5),
56     upperCritical = (1 << 4),
57     upperNonCritical = (1 << 3),
58     lowerNonRecoverable = (1 << 2),
59     lowerCritical = (1 << 1),
60     lowerNonCritical = (1 << 0),
61 };
62 
63 enum class IPMISensorEventEnableByte2 : uint8_t
64 {
65     eventMessagesEnable = (1 << 7),
66     sensorScanningEnable = (1 << 6),
67 };
68 
69 enum class IPMISensorEventEnableThresholds : uint8_t
70 {
71     nonRecoverableThreshold = (1 << 6),
72     criticalThreshold = (1 << 5),
73     nonCriticalThreshold = (1 << 4),
74     upperNonRecoverableGoingHigh = (1 << 3),
75     upperNonRecoverableGoingLow = (1 << 2),
76     upperCriticalGoingHigh = (1 << 1),
77     upperCriticalGoingLow = (1 << 0),
78     upperNonCriticalGoingHigh = (1 << 7),
79     upperNonCriticalGoingLow = (1 << 6),
80     lowerNonRecoverableGoingHigh = (1 << 5),
81     lowerNonRecoverableGoingLow = (1 << 4),
82     lowerCriticalGoingHigh = (1 << 3),
83     lowerCriticalGoingLow = (1 << 2),
84     lowerNonCriticalGoingHigh = (1 << 1),
85     lowerNonCriticalGoingLow = (1 << 0),
86 };
87 
88 enum class IPMIGetSensorEventEnableThresholds : uint8_t
89 {
90     lowerNonCriticalGoingLow = 0,
91     lowerNonCriticalGoingHigh = 1,
92     lowerCriticalGoingLow = 2,
93     lowerCriticalGoingHigh = 3,
94     lowerNonRecoverableGoingLow = 4,
95     lowerNonRecoverableGoingHigh = 5,
96     upperNonCriticalGoingLow = 6,
97     upperNonCriticalGoingHigh = 7,
98     upperCriticalGoingLow = 8,
99     upperCriticalGoingHigh = 9,
100     upperNonRecoverableGoingLow = 10,
101     upperNonRecoverableGoingHigh = 11,
102 };
103 
104 enum class IPMINetfnSensorCmds : ipmi_cmd_t
105 {
106     ipmiCmdGetDeviceSDRInfo = 0x20,
107     ipmiCmdGetDeviceSDR = 0x21,
108     ipmiCmdReserveDeviceSDRRepo = 0x22,
109     ipmiCmdSetSensorThreshold = 0x26,
110     ipmiCmdGetSensorThreshold = 0x27,
111     ipmiCmdGetSensorEventEnable = 0x29,
112     ipmiCmdGetSensorEventStatus = 0x2B,
113     ipmiCmdGetSensorReading = 0x2D,
114     ipmiCmdGetSensorType = 0x2F,
115     ipmiCmdSetSensorReadingAndEventStatus = 0x30,
116 };
117 
118 namespace ipmi
119 {
120 
121 SensorSubTree& getSensorTree()
122 {
123     static SensorSubTree sensorTree;
124     return sensorTree;
125 }
126 
127 static ipmi_ret_t
128     getSensorConnection(ipmi::Context::ptr ctx, uint8_t sensnum,
129                         std::string& connection, std::string& path,
130                         std::vector<std::string>* interfaces = nullptr)
131 {
132     auto& sensorTree = getSensorTree();
133     if (!getSensorSubtree(sensorTree) && sensorTree.empty())
134     {
135         return IPMI_CC_RESPONSE_ERROR;
136     }
137 
138     if (ctx == nullptr)
139     {
140         return IPMI_CC_RESPONSE_ERROR;
141     }
142 
143     path = getPathFromSensorNumber((ctx->lun << 8) | sensnum);
144     if (path.empty())
145     {
146         return IPMI_CC_INVALID_FIELD_REQUEST;
147     }
148 
149     for (const auto& sensor : sensorTree)
150     {
151         if (path == sensor.first)
152         {
153             connection = sensor.second.begin()->first;
154             if (interfaces)
155                 *interfaces = sensor.second.begin()->second;
156             break;
157         }
158     }
159 
160     return 0;
161 }
162 
163 struct IPMIThresholds
164 {
165     std::optional<uint8_t> warningLow;
166     std::optional<uint8_t> warningHigh;
167     std::optional<uint8_t> criticalLow;
168     std::optional<uint8_t> criticalHigh;
169 };
170 
171 } // namespace ipmi
172