📄 snmp_bc_sensor.c
字号:
/* -*- linux-c -*- * * (C) Copyright IBM Corp. 2004 * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. This * file and program are licensed under a BSD style license. See * the Copying file included with the OpenHPI distribution for * full licensing terms. * * Author(s): * Steve Sherman <stevees@us.ibm.com> */#include <snmp_bc_plugin.h>/** * snmp_bc_get_sensor_reading: * @hnd: Handler data pointer. * @rid: Resource ID. * @sid: Sensor ID. * @data: Location to store sensor's value (may be NULL). * @state: Location to store sensor's state (may be NULL). * * Retrieves a sensor's value and/or state. Both @data and @state * may be NULL, in which case this function can be used to test for * sensor presence. * * Return values: * SA_OK - Normal case. * SA_ERR_HPI_CAPABILITY - Resource doesn't have SAHPI_CAPABILITY_SENSOR. * SA_ERR_HPI_INVALID_REQUEST - Sensor is disabled. * SA_ERR_HPI_NOT_PRESENT - Sensor doesn't exist. * SA_ERR_HPI_INVALID_PARAMS - Pointer parameter(s) are NULL. **/SaErrorT snmp_bc_get_sensor_reading(void *hnd, SaHpiResourceIdT rid, SaHpiSensorNumT sid, SaHpiSensorReadingT *reading, SaHpiEventStateT *state){ SaErrorT err; SaHpiSensorReadingT working_reading; SaHpiEventStateT working_state; struct SensorInfo *sinfo; if (!hnd) { dbg("Invalid parameter."); return(SA_ERR_HPI_INVALID_PARAMS); } struct oh_handler_state *handle = (struct oh_handler_state *)hnd; struct snmp_bc_hnd *custom_handle = (struct snmp_bc_hnd *)handle->data; if (!custom_handle) { dbg("Invalid parameter."); return(SA_ERR_HPI_INVALID_PARAMS); } /* Check if resource exists and has sensor capabilities */ SaHpiRptEntryT *rpt = oh_get_resource_by_id(handle->rptcache, rid); if (!rpt) return(SA_ERR_HPI_INVALID_RESOURCE); if (!(rpt->ResourceCapabilities & SAHPI_CAPABILITY_SENSOR)) return(SA_ERR_HPI_CAPABILITY); /* Check if sensor exists and is enabled */ SaHpiRdrT *rdr = oh_get_rdr_by_type(handle->rptcache, rid, SAHPI_SENSOR_RDR, sid); if (rdr == NULL) return(SA_ERR_HPI_NOT_PRESENT); sinfo = (struct SensorInfo *)oh_get_rdr_data(handle->rptcache, rid, rdr->RecordId); if (sinfo == NULL) { dbg("No sensor data. Sensor=%s", rdr->IdString.Data); return(SA_ERR_HPI_INTERNAL_ERROR); } if (sinfo->sensor_enabled == SAHPI_FALSE) return(SA_ERR_HPI_INVALID_REQUEST); memset(&working_reading, 0, sizeof(SaHpiSensorReadingT)); working_state = SAHPI_ES_UNSPECIFIED; /************************************************************ * Get sensor's reading. * Need to go through this logic, since user may request just * the event state for a readable sensor. Need to translate * sensor reading to event in this case. ************************************************************/ if (rdr->RdrTypeUnion.SensorRec.DataFormat.IsSupported == SAHPI_TRUE) { err = snmp_bc_get_sensor_oid_reading(hnd, rid, sid, sinfo->mib.oid, &working_reading); if (err) { dbg("Cannot determine sensor's reading. Error=%s", oh_lookup_error(err)); return(err); } } else { working_reading.IsSupported = SAHPI_FALSE; } /****************************************************************** * Get sensor's event state. * Always get the event state, to reset the sensor's current state, * whether caller wants to know event state or not. ******************************************************************/ err = snmp_bc_get_sensor_eventstate(hnd, rid, sid, &working_reading, &working_state); if (err) { dbg("Cannot determine sensor's event state. Error=%s", oh_lookup_error(err)); return(err); }#if 0 { /* Debug section */ SaHpiTextBufferT buffer; dbg("Sensor=%s", rdr->IdString.Data); oh_decode_sensorreading(working_reading, rdr->RdrTypeUnion.SensorRec.DataFormat, &buffer); dbg(" Reading: %s.", buffer.Data); oh_decode_eventstate(working_state, rdr->RdrTypeUnion.SensorRec.Category, &buffer); dbg(" Event State: %s\n", buffer.Data); }#endif /* sinfo->cur_state = working_state; */ if (reading) memcpy(reading, &working_reading, sizeof(SaHpiSensorReadingT)); if (state) memcpy(state, &working_state, sizeof(SaHpiEventStateT)); return(SA_OK);}/** * snmp_bc_get_sensor_eventstate: * @hnd: Handler data pointer. * @rid: Resource ID. * @sid: Sensor ID. * @reading: Location of sensor's reading * @state: Location to store sensor's state. * * Translates and sensor's reading into an event state(s). * * Return values: * SA_OK - Normal case. * SA_ERR_HPI_CAPABILITY - Resource doesn't have SAHPI_CAPABILITY_SENSOR. * SA_ERR_HPI_INVALID_REQUEST - Sensor is disabled. * SA_ERR_HPI_INVALID_PARAMS - Pointer parameter(s) are NULL. * SA_ERR_HPI_NOT_PRESENT - Sensor doesn't exist. **/SaErrorT snmp_bc_get_sensor_eventstate(void *hnd, SaHpiResourceIdT rid, SaHpiSensorNumT sid, SaHpiSensorReadingT *reading, SaHpiEventStateT *state){ int i; struct SensorInfo *sinfo; struct oh_handler_state *handle = (struct oh_handler_state *)hnd; if (!hnd || !reading || !state) { dbg("Invalid parameter."); return(SA_ERR_HPI_INVALID_PARAMS); } /* Check if resource exists and has sensor capabilities */ SaHpiRptEntryT *rpt = oh_get_resource_by_id(handle->rptcache, rid); if (!rpt) return(SA_ERR_HPI_INVALID_RESOURCE); if (!(rpt->ResourceCapabilities & SAHPI_CAPABILITY_SENSOR)) return(SA_ERR_HPI_CAPABILITY); /* Check if sensor exist and is enabled */ SaHpiRdrT *rdr = oh_get_rdr_by_type(handle->rptcache, rid, SAHPI_SENSOR_RDR, sid); if (rdr == NULL) return(SA_ERR_HPI_NOT_PRESENT); sinfo = (struct SensorInfo *)oh_get_rdr_data(handle->rptcache, rid, rdr->RecordId); if (sinfo == NULL) { dbg("No sensor data. Sensor=%s", rdr->IdString.Data); return(SA_ERR_HPI_INTERNAL_ERROR); } if (sinfo->sensor_enabled == SAHPI_FALSE) return(SA_ERR_HPI_INVALID_REQUEST); /* If sensor is not readable, return current event state */ if (rdr->RdrTypeUnion.SensorRec.DataFormat.IsSupported == SAHPI_FALSE) { *state = sinfo->cur_state; return(SA_OK); } /*************************************************************************** * Translate reading into event state. Algorithm is: * - If sensor is a threshold and has readable thresholds. * - If so, check from most severe to least * - If not found or not a threshold value, search reading2event array. * - Check for Ranges supported; return after first match. * - Nominal only - reading must match nominal value * - Max && Min - min value <= reading <= max value * - Max only - reading > max value * - Min only - reading < min value * - else SAHPI_ES_UNSPECIFIED ***************************************************************************/ if (rdr->RdrTypeUnion.SensorRec.Category == SAHPI_EC_THRESHOLD && rdr->RdrTypeUnion.SensorRec.ThresholdDefn.ReadThold != 0) { SaHpiSensorThresholdsT thres; memset(&thres, 0, sizeof(SaHpiSensorThresholdsT)); SaErrorT err = snmp_bc_get_sensor_thresholds(hnd, rid, sid, &thres); if (err) { dbg("Cannot get sensor thresholds for Sensor=%s. Error=%s", rdr->IdString.Data, oh_lookup_error(err)); return(err); } if (thres.LowCritical.IsSupported == SAHPI_TRUE) { if (oh_compare_sensorreading(reading->Type, reading, &thres.LowCritical) <= 0) { *state = SAHPI_ES_LOWER_CRIT | SAHPI_ES_LOWER_MAJOR | SAHPI_ES_LOWER_MINOR; return(SA_OK); } } if (thres.LowMajor.IsSupported == SAHPI_TRUE) { if (oh_compare_sensorreading(reading->Type, reading, &thres.LowMajor) <= 0) { *state = SAHPI_ES_LOWER_MAJOR | SAHPI_ES_LOWER_MINOR; return(SA_OK); } } if (thres.LowMinor.IsSupported == SAHPI_TRUE) { if (oh_compare_sensorreading(reading->Type, reading, &thres.LowMinor) <= 0) { *state = SAHPI_ES_LOWER_MINOR; return(SA_OK); } } if (thres.UpCritical.IsSupported == SAHPI_TRUE) { if (oh_compare_sensorreading(reading->Type, reading, &thres.UpCritical) >= 0) { *state = SAHPI_ES_UPPER_CRIT | SAHPI_ES_UPPER_MAJOR | SAHPI_ES_UPPER_MINOR; return(SA_OK); } } if (thres.UpMajor.IsSupported == SAHPI_TRUE) { if (oh_compare_sensorreading(reading->Type, reading, &thres.UpMajor) >= 0) { *state = SAHPI_ES_UPPER_MAJOR | SAHPI_ES_UPPER_MINOR; return(SA_OK); } } if (thres.UpMinor.IsSupported == SAHPI_TRUE) { if (oh_compare_sensorreading(reading->Type, reading, &thres.UpMinor) >= 0) { *state = SAHPI_ES_UPPER_MINOR; return(SA_OK); } } } /* Check reading2event array */ for (i=0; i < SNMP_BC_MAX_SENSOR_READING_MAP_ARRAY_SIZE && sinfo->reading2event[i].num != 0; i++) { /* reading == nominal */ if (sinfo->reading2event[i].rangemap.Flags & SAHPI_SRF_NOMINAL) { if (oh_compare_sensorreading(reading->Type, reading, &sinfo->reading2event[i].rangemap.Nominal) == 0) { *state = sinfo->reading2event[i].state; return(SA_OK); } } /* min <= reading <= max */ if (sinfo->reading2event[i].rangemap.Flags & SAHPI_SRF_MAX && sinfo->reading2event[i].rangemap.Flags & SAHPI_SRF_MIN) { if (oh_compare_sensorreading(reading->Type, reading, &sinfo->reading2event[i].rangemap.Min) >= 0 && oh_compare_sensorreading(reading->Type, reading, &sinfo->reading2event[i].rangemap.Max) <= 0) { *state = sinfo->reading2event[i].state; return(SA_OK); } } /* reading > max */ if (sinfo->reading2event[i].rangemap.Flags & SAHPI_SRF_MAX && !(sinfo->reading2event[i].rangemap.Flags & SAHPI_SRF_MIN)) { if (oh_compare_sensorreading(reading->Type, reading, &sinfo->reading2event[i].rangemap.Max) > 0) { *state = sinfo->reading2event[i].state; return(SA_OK); } } /* reading < min */ if (!(sinfo->reading2event[i].rangemap.Flags & SAHPI_SRF_MAX) && sinfo->reading2event[i].rangemap.Flags & SAHPI_SRF_MIN) { if (oh_compare_sensorreading(reading->Type, reading, &sinfo->reading2event[i].rangemap.Min) < 0) { *state = sinfo->reading2event[i].state; return(SA_OK); } } } /* Unfortunately for thresholds, this also means normal */ *state = SAHPI_ES_UNSPECIFIED; return(SA_OK);}#define get_threshold(thdmask, thdname) \do { \ if (rdr->RdrTypeUnion.SensorRec.ThresholdDefn.ReadThold & thdmask) { \ if (sinfo->mib.threshold_oids.thdname == NULL || \ sinfo->mib.threshold_oids.thdname[0] == '\0') { \ dbg("No OID defined for readable threshold. Sensor=%s", rdr->IdString.Data); \ return(SA_ERR_HPI_INTERNAL_ERROR); \ } \ SaErrorT err = snmp_bc_get_sensor_oid_reading(hnd, rid, sid, \ sinfo->mib.threshold_oids.thdname, \ &(working.thdname)); \ if (err) return(err); \ if (working.thdname.Type == SAHPI_SENSOR_READING_TYPE_BUFFER) { \ dbg("Sensor type SAHPI_SENSOR_READING_TYPE_BUFFER cannot have thresholds. Sensor=%s", \ rdr->IdString.Data); \ return(SA_ERR_HPI_INTERNAL_ERROR); \ } \ found_thresholds = found_thresholds | thdmask; \ } \ else { \ working.thdname.IsSupported = SAHPI_FALSE; \ } \} while(0)/** * snmp_bc_get_sensor_thresholds: * @hnd: Handler data pointer. * @rid: Resource ID. * @sid: Sensor ID. * @thres: Location to store sensor's threshold values. * * Retreives sensor's threshold values, if defined. * * Return values: * SA_OK - Normal case. * SA_ERR_HPI_CAPABILITY - Resource doesn't have SAHPI_CAPABILITY_SENSOR. * SA_ERR_HPI_INVALID_CMD - Sensor is not threshold type, has accessible or readable thresholds. * SA_ERR_HPI_INVALID_PARAMS - Pointer parameter(s) are NULL. * SA_ERR_HPI_NOT_PRESENT - Sensor doesn't exist. **/SaErrorT snmp_bc_get_sensor_thresholds(void *hnd, SaHpiResourceIdT rid, SaHpiSensorNumT sid, SaHpiSensorThresholdsT *thres){ int upper_thresholds, lower_thresholds; SaHpiSensorThdMaskT found_thresholds; SaHpiSensorThresholdsT working; struct SensorInfo *sinfo; struct oh_handler_state *handle = (struct oh_handler_state *)hnd; if (!hnd || !thres) { dbg("Invalid parameter."); return(SA_ERR_HPI_INVALID_PARAMS); } /* Check if resource exists and has sensor capabilities */ SaHpiRptEntryT *rpt = oh_get_resource_by_id(handle->rptcache, rid); if (!rpt) return(SA_ERR_HPI_INVALID_RESOURCE); if (!(rpt->ResourceCapabilities & SAHPI_CAPABILITY_SENSOR)) return(SA_ERR_HPI_CAPABILITY); /* Check if sensor exits and has readable thresholds */ SaHpiRdrT *rdr = oh_get_rdr_by_type(handle->rptcache, rid, SAHPI_SENSOR_RDR, sid); if (rdr == NULL) return(SA_ERR_HPI_NOT_PRESENT); sinfo = (struct SensorInfo *)oh_get_rdr_data(handle->rptcache, rid, rdr->RecordId); if (sinfo == NULL) { dbg("No sensor data. Sensor=%s", rdr->IdString.Data); return(SA_ERR_HPI_INTERNAL_ERROR); } if (rdr->RdrTypeUnion.SensorRec.Category != SAHPI_EC_THRESHOLD || rdr->RdrTypeUnion.SensorRec.ThresholdDefn.IsAccessible == SAHPI_FALSE || rdr->RdrTypeUnion.SensorRec.ThresholdDefn.ReadThold == 0) return(SA_ERR_HPI_INVALID_CMD); memset(&working, 0, sizeof(SaHpiSensorThresholdsT)); found_thresholds = lower_thresholds = upper_thresholds = 0; get_threshold(SAHPI_STM_LOW_MINOR, LowMinor); if (found_thresholds & SAHPI_STM_LOW_MINOR) lower_thresholds++; get_threshold(SAHPI_STM_LOW_MAJOR, LowMajor); if (found_thresholds & SAHPI_STM_LOW_MAJOR) lower_thresholds++; get_threshold(SAHPI_STM_LOW_CRIT, LowCritical); if (found_thresholds & SAHPI_STM_LOW_CRIT) lower_thresholds++; get_threshold(SAHPI_STM_UP_MINOR, UpMinor); if (found_thresholds & SAHPI_STM_UP_MINOR) upper_thresholds++; get_threshold(SAHPI_STM_UP_MAJOR, UpMajor); if (found_thresholds & SAHPI_STM_UP_MAJOR) upper_thresholds++; get_threshold(SAHPI_STM_UP_CRIT, UpCritical); if (found_thresholds & SAHPI_STM_UP_CRIT) upper_thresholds++; /************************************************************************ * Find Hysteresis Values * * Hardware can define hysteresis values two ways: * * - As delta values as defined in the spec. In this case, * PosThdHysteresis and/or NegThdHysteresis values are defined * and this routine just returns those values. * * - Total values - as in threshold is 80 degrees; positive hysteresis is * defined to be 78 degrees. In this case, TotalPosThdHysteresis and/or * TotalNegThdHysteresis are defined and this routine needs to make * the required calculations to return to the user a delta value. Total * values can only be used if: * 1) there is one upper/lower threshold defined. * 2) Total values cannot be of type SAHPI_SENSOR_READING_TYPE_UINT64 or * SAHPI_SENSOR_READING_TYPE_BUFFER. * * Code can support a delta value for one set of thresholds (upper or * lower) and a total value for the opposite set. *************************************************************************/ if (sinfo->mib.threshold_oids.NegThdHysteresis) { get_threshold(SAHPI_STM_LOW_HYSTERESIS, NegThdHysteresis); } if (sinfo->mib.threshold_oids.PosThdHysteresis) { get_threshold(SAHPI_STM_UP_HYSTERESIS, PosThdHysteresis); } /* Negative Total Hysteresis - applies to lower thresholds */ if (sinfo->mib.threshold_oids.TotalNegThdHysteresis) { SaHpiSensorReadingT reading; if (found_thresholds & SAHPI_STM_LOW_HYSTERESIS) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -