1*77e6fe7aSGilbert Chen #include "event_manager.hpp" 2*77e6fe7aSGilbert Chen 3*77e6fe7aSGilbert Chen #include "libpldm/utils.h" 4*77e6fe7aSGilbert Chen 5*77e6fe7aSGilbert Chen #include "terminus_manager.hpp" 6*77e6fe7aSGilbert Chen 7*77e6fe7aSGilbert Chen #include <phosphor-logging/lg2.hpp> 8*77e6fe7aSGilbert Chen #include <xyz/openbmc_project/Logging/Entry/server.hpp> 9*77e6fe7aSGilbert Chen 10*77e6fe7aSGilbert Chen #include <cerrno> 11*77e6fe7aSGilbert Chen #include <memory> 12*77e6fe7aSGilbert Chen 13*77e6fe7aSGilbert Chen PHOSPHOR_LOG2_USING; 14*77e6fe7aSGilbert Chen 15*77e6fe7aSGilbert Chen namespace pldm 16*77e6fe7aSGilbert Chen { 17*77e6fe7aSGilbert Chen namespace platform_mc 18*77e6fe7aSGilbert Chen { 19*77e6fe7aSGilbert Chen namespace fs = std::filesystem; 20*77e6fe7aSGilbert Chen 21*77e6fe7aSGilbert Chen int EventManager::handlePlatformEvent( 22*77e6fe7aSGilbert Chen pldm_tid_t tid, uint16_t eventId, uint8_t eventClass, 23*77e6fe7aSGilbert Chen const uint8_t* eventData, size_t eventDataSize) 24*77e6fe7aSGilbert Chen { 25*77e6fe7aSGilbert Chen /* EventClass sensorEvent `Table 11 - PLDM Event Types` DSP0248 */ 26*77e6fe7aSGilbert Chen if (eventClass == PLDM_SENSOR_EVENT) 27*77e6fe7aSGilbert Chen { 28*77e6fe7aSGilbert Chen uint16_t sensorId = 0; 29*77e6fe7aSGilbert Chen uint8_t sensorEventClassType = 0; 30*77e6fe7aSGilbert Chen size_t eventClassDataOffset = 0; 31*77e6fe7aSGilbert Chen auto rc = decode_sensor_event_data(eventData, eventDataSize, &sensorId, 32*77e6fe7aSGilbert Chen &sensorEventClassType, 33*77e6fe7aSGilbert Chen &eventClassDataOffset); 34*77e6fe7aSGilbert Chen if (rc) 35*77e6fe7aSGilbert Chen { 36*77e6fe7aSGilbert Chen lg2::error( 37*77e6fe7aSGilbert Chen "Failed to decode sensor event data from terminus ID {TID}, event class {CLASS}, event ID {EVENTID} with return code {RC}.", 38*77e6fe7aSGilbert Chen "TID", tid, "CLASS", eventClass, "EVENTID", eventId, "RC", rc); 39*77e6fe7aSGilbert Chen return rc; 40*77e6fe7aSGilbert Chen } 41*77e6fe7aSGilbert Chen switch (sensorEventClassType) 42*77e6fe7aSGilbert Chen { 43*77e6fe7aSGilbert Chen case PLDM_NUMERIC_SENSOR_STATE: 44*77e6fe7aSGilbert Chen { 45*77e6fe7aSGilbert Chen const uint8_t* sensorData = eventData + eventClassDataOffset; 46*77e6fe7aSGilbert Chen size_t sensorDataLength = eventDataSize - eventClassDataOffset; 47*77e6fe7aSGilbert Chen return processNumericSensorEvent(tid, sensorId, sensorData, 48*77e6fe7aSGilbert Chen sensorDataLength); 49*77e6fe7aSGilbert Chen } 50*77e6fe7aSGilbert Chen case PLDM_STATE_SENSOR_STATE: 51*77e6fe7aSGilbert Chen case PLDM_SENSOR_OP_STATE: 52*77e6fe7aSGilbert Chen default: 53*77e6fe7aSGilbert Chen lg2::info( 54*77e6fe7aSGilbert Chen "Unsupported class type {CLASSTYPE} for the sensor event from terminus ID {TID} sensorId {SID}", 55*77e6fe7aSGilbert Chen "CLASSTYPE", sensorEventClassType, "TID", tid, "SID", 56*77e6fe7aSGilbert Chen sensorId); 57*77e6fe7aSGilbert Chen return PLDM_ERROR; 58*77e6fe7aSGilbert Chen } 59*77e6fe7aSGilbert Chen } 60*77e6fe7aSGilbert Chen 61*77e6fe7aSGilbert Chen lg2::info("Unsupported class type {CLASSTYPE}", "CLASSTYPE", eventClass); 62*77e6fe7aSGilbert Chen 63*77e6fe7aSGilbert Chen return PLDM_ERROR; 64*77e6fe7aSGilbert Chen } 65*77e6fe7aSGilbert Chen 66*77e6fe7aSGilbert Chen int EventManager::processNumericSensorEvent(pldm_tid_t tid, uint16_t sensorId, 67*77e6fe7aSGilbert Chen const uint8_t* sensorData, 68*77e6fe7aSGilbert Chen size_t sensorDataLength) 69*77e6fe7aSGilbert Chen { 70*77e6fe7aSGilbert Chen uint8_t eventState = 0; 71*77e6fe7aSGilbert Chen uint8_t previousEventState = 0; 72*77e6fe7aSGilbert Chen uint8_t sensorDataSize = 0; 73*77e6fe7aSGilbert Chen uint32_t presentReading; 74*77e6fe7aSGilbert Chen auto rc = decode_numeric_sensor_data( 75*77e6fe7aSGilbert Chen sensorData, sensorDataLength, &eventState, &previousEventState, 76*77e6fe7aSGilbert Chen &sensorDataSize, &presentReading); 77*77e6fe7aSGilbert Chen if (rc) 78*77e6fe7aSGilbert Chen { 79*77e6fe7aSGilbert Chen lg2::error( 80*77e6fe7aSGilbert Chen "Failed to decode numericSensorState event for terminus ID {TID}, error {RC} ", 81*77e6fe7aSGilbert Chen "TID", tid, "RC", rc); 82*77e6fe7aSGilbert Chen return rc; 83*77e6fe7aSGilbert Chen } 84*77e6fe7aSGilbert Chen 85*77e6fe7aSGilbert Chen double value = static_cast<double>(presentReading); 86*77e6fe7aSGilbert Chen lg2::error( 87*77e6fe7aSGilbert Chen "processNumericSensorEvent tid {TID}, sensorID {SID} value {VAL} previousState {PSTATE} eventState {ESTATE}", 88*77e6fe7aSGilbert Chen "TID", tid, "SID", sensorId, "VAL", value, "PSTATE", previousEventState, 89*77e6fe7aSGilbert Chen "ESTATE", eventState); 90*77e6fe7aSGilbert Chen 91*77e6fe7aSGilbert Chen if (!termini.contains(tid) || !termini[tid]) 92*77e6fe7aSGilbert Chen { 93*77e6fe7aSGilbert Chen lg2::error("Terminus ID {TID} is not in the managing list.", "TID", 94*77e6fe7aSGilbert Chen tid); 95*77e6fe7aSGilbert Chen return PLDM_ERROR; 96*77e6fe7aSGilbert Chen } 97*77e6fe7aSGilbert Chen 98*77e6fe7aSGilbert Chen auto& terminus = termini[tid]; 99*77e6fe7aSGilbert Chen 100*77e6fe7aSGilbert Chen auto sensor = terminus->getSensorObject(sensorId); 101*77e6fe7aSGilbert Chen if (!sensor) 102*77e6fe7aSGilbert Chen { 103*77e6fe7aSGilbert Chen lg2::error( 104*77e6fe7aSGilbert Chen "Terminus ID {TID} has no sensor object with sensor ID {SID}.", 105*77e6fe7aSGilbert Chen "TID", tid, "SID", sensorId); 106*77e6fe7aSGilbert Chen return PLDM_ERROR; 107*77e6fe7aSGilbert Chen } 108*77e6fe7aSGilbert Chen 109*77e6fe7aSGilbert Chen switch (previousEventState) 110*77e6fe7aSGilbert Chen { 111*77e6fe7aSGilbert Chen case PLDM_SENSOR_UNKNOWN: 112*77e6fe7aSGilbert Chen case PLDM_SENSOR_NORMAL: 113*77e6fe7aSGilbert Chen { 114*77e6fe7aSGilbert Chen switch (eventState) 115*77e6fe7aSGilbert Chen { 116*77e6fe7aSGilbert Chen case PLDM_SENSOR_UPPERFATAL: 117*77e6fe7aSGilbert Chen case PLDM_SENSOR_UPPERCRITICAL: 118*77e6fe7aSGilbert Chen { 119*77e6fe7aSGilbert Chen sensor->triggerThresholdEvent(pldm::utils::Level::WARNING, 120*77e6fe7aSGilbert Chen pldm::utils::Direction::HIGH, 121*77e6fe7aSGilbert Chen value, true, true); 122*77e6fe7aSGilbert Chen return sensor->triggerThresholdEvent( 123*77e6fe7aSGilbert Chen pldm::utils::Level::CRITICAL, 124*77e6fe7aSGilbert Chen pldm::utils::Direction::HIGH, value, true, true); 125*77e6fe7aSGilbert Chen } 126*77e6fe7aSGilbert Chen case PLDM_SENSOR_UPPERWARNING: 127*77e6fe7aSGilbert Chen { 128*77e6fe7aSGilbert Chen return sensor->triggerThresholdEvent( 129*77e6fe7aSGilbert Chen pldm::utils::Level::WARNING, 130*77e6fe7aSGilbert Chen pldm::utils::Direction::HIGH, value, true, true); 131*77e6fe7aSGilbert Chen } 132*77e6fe7aSGilbert Chen case PLDM_SENSOR_NORMAL: 133*77e6fe7aSGilbert Chen break; 134*77e6fe7aSGilbert Chen case PLDM_SENSOR_LOWERWARNING: 135*77e6fe7aSGilbert Chen { 136*77e6fe7aSGilbert Chen return sensor->triggerThresholdEvent( 137*77e6fe7aSGilbert Chen pldm::utils::Level::WARNING, 138*77e6fe7aSGilbert Chen pldm::utils::Direction::LOW, value, true, true); 139*77e6fe7aSGilbert Chen } 140*77e6fe7aSGilbert Chen case PLDM_SENSOR_LOWERCRITICAL: 141*77e6fe7aSGilbert Chen case PLDM_SENSOR_LOWERFATAL: 142*77e6fe7aSGilbert Chen { 143*77e6fe7aSGilbert Chen sensor->triggerThresholdEvent(pldm::utils::Level::WARNING, 144*77e6fe7aSGilbert Chen pldm::utils::Direction::LOW, 145*77e6fe7aSGilbert Chen value, true, true); 146*77e6fe7aSGilbert Chen return sensor->triggerThresholdEvent( 147*77e6fe7aSGilbert Chen pldm::utils::Level::CRITICAL, 148*77e6fe7aSGilbert Chen pldm::utils::Direction::LOW, value, true, true); 149*77e6fe7aSGilbert Chen } 150*77e6fe7aSGilbert Chen default: 151*77e6fe7aSGilbert Chen break; 152*77e6fe7aSGilbert Chen } 153*77e6fe7aSGilbert Chen break; 154*77e6fe7aSGilbert Chen } 155*77e6fe7aSGilbert Chen case PLDM_SENSOR_LOWERWARNING: 156*77e6fe7aSGilbert Chen { 157*77e6fe7aSGilbert Chen switch (eventState) 158*77e6fe7aSGilbert Chen { 159*77e6fe7aSGilbert Chen case PLDM_SENSOR_UPPERFATAL: 160*77e6fe7aSGilbert Chen case PLDM_SENSOR_UPPERCRITICAL: 161*77e6fe7aSGilbert Chen break; 162*77e6fe7aSGilbert Chen case PLDM_SENSOR_UPPERWARNING: 163*77e6fe7aSGilbert Chen { 164*77e6fe7aSGilbert Chen sensor->triggerThresholdEvent(pldm::utils::Level::WARNING, 165*77e6fe7aSGilbert Chen pldm::utils::Direction::LOW, 166*77e6fe7aSGilbert Chen value, false, false); 167*77e6fe7aSGilbert Chen return sensor->triggerThresholdEvent( 168*77e6fe7aSGilbert Chen pldm::utils::Level::WARNING, 169*77e6fe7aSGilbert Chen pldm::utils::Direction::HIGH, value, true, true); 170*77e6fe7aSGilbert Chen } 171*77e6fe7aSGilbert Chen case PLDM_SENSOR_NORMAL: 172*77e6fe7aSGilbert Chen { 173*77e6fe7aSGilbert Chen return sensor->triggerThresholdEvent( 174*77e6fe7aSGilbert Chen pldm::utils::Level::WARNING, 175*77e6fe7aSGilbert Chen pldm::utils::Direction::LOW, value, false, false); 176*77e6fe7aSGilbert Chen } 177*77e6fe7aSGilbert Chen case PLDM_SENSOR_LOWERWARNING: 178*77e6fe7aSGilbert Chen break; 179*77e6fe7aSGilbert Chen case PLDM_SENSOR_LOWERCRITICAL: 180*77e6fe7aSGilbert Chen case PLDM_SENSOR_LOWERFATAL: 181*77e6fe7aSGilbert Chen { 182*77e6fe7aSGilbert Chen return sensor->triggerThresholdEvent( 183*77e6fe7aSGilbert Chen pldm::utils::Level::CRITICAL, 184*77e6fe7aSGilbert Chen pldm::utils::Direction::LOW, value, true, true); 185*77e6fe7aSGilbert Chen } 186*77e6fe7aSGilbert Chen default: 187*77e6fe7aSGilbert Chen break; 188*77e6fe7aSGilbert Chen } 189*77e6fe7aSGilbert Chen break; 190*77e6fe7aSGilbert Chen } 191*77e6fe7aSGilbert Chen case PLDM_SENSOR_LOWERCRITICAL: 192*77e6fe7aSGilbert Chen case PLDM_SENSOR_LOWERFATAL: 193*77e6fe7aSGilbert Chen { 194*77e6fe7aSGilbert Chen switch (eventState) 195*77e6fe7aSGilbert Chen { 196*77e6fe7aSGilbert Chen case PLDM_SENSOR_UPPERFATAL: 197*77e6fe7aSGilbert Chen case PLDM_SENSOR_UPPERCRITICAL: 198*77e6fe7aSGilbert Chen case PLDM_SENSOR_UPPERWARNING: 199*77e6fe7aSGilbert Chen break; 200*77e6fe7aSGilbert Chen case PLDM_SENSOR_NORMAL: 201*77e6fe7aSGilbert Chen { 202*77e6fe7aSGilbert Chen sensor->triggerThresholdEvent(pldm::utils::Level::CRITICAL, 203*77e6fe7aSGilbert Chen pldm::utils::Direction::LOW, 204*77e6fe7aSGilbert Chen value, false, false); 205*77e6fe7aSGilbert Chen sensor->triggerThresholdEvent(pldm::utils::Level::WARNING, 206*77e6fe7aSGilbert Chen pldm::utils::Direction::LOW, 207*77e6fe7aSGilbert Chen value, true, true); 208*77e6fe7aSGilbert Chen return sensor->triggerThresholdEvent( 209*77e6fe7aSGilbert Chen pldm::utils::Level::WARNING, 210*77e6fe7aSGilbert Chen pldm::utils::Direction::LOW, value, false, false); 211*77e6fe7aSGilbert Chen } 212*77e6fe7aSGilbert Chen case PLDM_SENSOR_LOWERWARNING: 213*77e6fe7aSGilbert Chen { 214*77e6fe7aSGilbert Chen sensor->triggerThresholdEvent(pldm::utils::Level::CRITICAL, 215*77e6fe7aSGilbert Chen pldm::utils::Direction::LOW, 216*77e6fe7aSGilbert Chen value, false, false); 217*77e6fe7aSGilbert Chen return sensor->triggerThresholdEvent( 218*77e6fe7aSGilbert Chen pldm::utils::Level::WARNING, 219*77e6fe7aSGilbert Chen pldm::utils::Direction::LOW, value, true, true); 220*77e6fe7aSGilbert Chen } 221*77e6fe7aSGilbert Chen case PLDM_SENSOR_LOWERCRITICAL: 222*77e6fe7aSGilbert Chen case PLDM_SENSOR_LOWERFATAL: 223*77e6fe7aSGilbert Chen default: 224*77e6fe7aSGilbert Chen break; 225*77e6fe7aSGilbert Chen } 226*77e6fe7aSGilbert Chen break; 227*77e6fe7aSGilbert Chen } 228*77e6fe7aSGilbert Chen case PLDM_SENSOR_UPPERFATAL: 229*77e6fe7aSGilbert Chen case PLDM_SENSOR_UPPERCRITICAL: 230*77e6fe7aSGilbert Chen { 231*77e6fe7aSGilbert Chen switch (eventState) 232*77e6fe7aSGilbert Chen { 233*77e6fe7aSGilbert Chen case PLDM_SENSOR_UPPERFATAL: 234*77e6fe7aSGilbert Chen case PLDM_SENSOR_UPPERCRITICAL: 235*77e6fe7aSGilbert Chen break; 236*77e6fe7aSGilbert Chen case PLDM_SENSOR_UPPERWARNING: 237*77e6fe7aSGilbert Chen { 238*77e6fe7aSGilbert Chen sensor->triggerThresholdEvent(pldm::utils::Level::CRITICAL, 239*77e6fe7aSGilbert Chen pldm::utils::Direction::HIGH, 240*77e6fe7aSGilbert Chen value, false, false); 241*77e6fe7aSGilbert Chen return sensor->triggerThresholdEvent( 242*77e6fe7aSGilbert Chen pldm::utils::Level::WARNING, 243*77e6fe7aSGilbert Chen pldm::utils::Direction::HIGH, value, true, true); 244*77e6fe7aSGilbert Chen } 245*77e6fe7aSGilbert Chen case PLDM_SENSOR_NORMAL: 246*77e6fe7aSGilbert Chen { 247*77e6fe7aSGilbert Chen sensor->triggerThresholdEvent(pldm::utils::Level::CRITICAL, 248*77e6fe7aSGilbert Chen pldm::utils::Direction::HIGH, 249*77e6fe7aSGilbert Chen value, false, false); 250*77e6fe7aSGilbert Chen sensor->triggerThresholdEvent(pldm::utils::Level::WARNING, 251*77e6fe7aSGilbert Chen pldm::utils::Direction::HIGH, 252*77e6fe7aSGilbert Chen value, true, true); 253*77e6fe7aSGilbert Chen return sensor->triggerThresholdEvent( 254*77e6fe7aSGilbert Chen pldm::utils::Level::WARNING, 255*77e6fe7aSGilbert Chen pldm::utils::Direction::HIGH, value, false, false); 256*77e6fe7aSGilbert Chen } 257*77e6fe7aSGilbert Chen case PLDM_SENSOR_LOWERWARNING: 258*77e6fe7aSGilbert Chen case PLDM_SENSOR_LOWERCRITICAL: 259*77e6fe7aSGilbert Chen case PLDM_SENSOR_LOWERFATAL: 260*77e6fe7aSGilbert Chen default: 261*77e6fe7aSGilbert Chen break; 262*77e6fe7aSGilbert Chen } 263*77e6fe7aSGilbert Chen break; 264*77e6fe7aSGilbert Chen } 265*77e6fe7aSGilbert Chen case PLDM_SENSOR_UPPERWARNING: 266*77e6fe7aSGilbert Chen { 267*77e6fe7aSGilbert Chen switch (eventState) 268*77e6fe7aSGilbert Chen { 269*77e6fe7aSGilbert Chen case PLDM_SENSOR_UPPERFATAL: 270*77e6fe7aSGilbert Chen case PLDM_SENSOR_UPPERCRITICAL: 271*77e6fe7aSGilbert Chen { 272*77e6fe7aSGilbert Chen return sensor->triggerThresholdEvent( 273*77e6fe7aSGilbert Chen pldm::utils::Level::CRITICAL, 274*77e6fe7aSGilbert Chen pldm::utils::Direction::HIGH, value, true, true); 275*77e6fe7aSGilbert Chen } 276*77e6fe7aSGilbert Chen case PLDM_SENSOR_UPPERWARNING: 277*77e6fe7aSGilbert Chen break; 278*77e6fe7aSGilbert Chen case PLDM_SENSOR_NORMAL: 279*77e6fe7aSGilbert Chen { 280*77e6fe7aSGilbert Chen return sensor->triggerThresholdEvent( 281*77e6fe7aSGilbert Chen pldm::utils::Level::WARNING, 282*77e6fe7aSGilbert Chen pldm::utils::Direction::HIGH, value, false, false); 283*77e6fe7aSGilbert Chen } 284*77e6fe7aSGilbert Chen case PLDM_SENSOR_LOWERWARNING: 285*77e6fe7aSGilbert Chen { 286*77e6fe7aSGilbert Chen sensor->triggerThresholdEvent(pldm::utils::Level::WARNING, 287*77e6fe7aSGilbert Chen pldm::utils::Direction::HIGH, 288*77e6fe7aSGilbert Chen value, false, false); 289*77e6fe7aSGilbert Chen return sensor->triggerThresholdEvent( 290*77e6fe7aSGilbert Chen pldm::utils::Level::WARNING, 291*77e6fe7aSGilbert Chen pldm::utils::Direction::LOW, value, true, true); 292*77e6fe7aSGilbert Chen } 293*77e6fe7aSGilbert Chen case PLDM_SENSOR_LOWERCRITICAL: 294*77e6fe7aSGilbert Chen case PLDM_SENSOR_LOWERFATAL: 295*77e6fe7aSGilbert Chen default: 296*77e6fe7aSGilbert Chen break; 297*77e6fe7aSGilbert Chen } 298*77e6fe7aSGilbert Chen break; 299*77e6fe7aSGilbert Chen } 300*77e6fe7aSGilbert Chen default: 301*77e6fe7aSGilbert Chen break; 302*77e6fe7aSGilbert Chen } 303*77e6fe7aSGilbert Chen 304*77e6fe7aSGilbert Chen return PLDM_SUCCESS; 305*77e6fe7aSGilbert Chen } 306*77e6fe7aSGilbert Chen 307*77e6fe7aSGilbert Chen } // namespace platform_mc 308*77e6fe7aSGilbert Chen } // namespace pldm 309