📄 sahpi_struct_utils.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): * Sean Dague <sdague@users.sf.net> * Steve Sherman <stevees@us.ibm.com> * Contributors: * Racing Guo <racing.guo@intel.com> */#include <glib.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <ctype.h>#include <errno.h>#include <SaHpi.h>#include <oh_utils.h>static inline SaErrorT oh_init_bigtext(oh_big_textbuffer *big_buffer);static inline SaErrorT oh_append_bigtext(oh_big_textbuffer *big_buffer, const char *from);static inline SaErrorT oh_copy_bigtext(oh_big_textbuffer *dest, const oh_big_textbuffer *from);static SaErrorT oh_append_offset(oh_big_textbuffer *buffer, int offsets);static SaErrorT oh_build_sensorrec(oh_big_textbuffer *buffer, const SaHpiSensorRecT *sensor, int offsets);static SaErrorT oh_build_sensordataformat(oh_big_textbuffer *buffer, const SaHpiSensorDataFormatT *format, int offsets);static SaErrorT oh_build_sensorthddefn(oh_big_textbuffer *buffer, const SaHpiSensorThdDefnT *tdef, int offsets);static SaErrorT oh_build_threshold_mask(oh_big_textbuffer *buffer, const SaHpiSensorThdMaskT tmask, int offsets);static SaErrorT oh_build_textbuffer(oh_big_textbuffer *buffer, const SaHpiTextBufferT *textbuffer, int offsets);static SaErrorT oh_build_ctrlrec(oh_big_textbuffer *textbuf, const SaHpiCtrlRecT *ctrlrec, int offsets);static SaErrorT oh_build_invrec(oh_big_textbuffer *textbuff, const SaHpiInventoryRecT *invrec, int offsets);static SaErrorT oh_build_wdogrec(oh_big_textbuffer *textbuff, const SaHpiWatchdogRecT *wdogrec, int offsets);static SaErrorT oh_build_annrec(oh_big_textbuffer *textbuff, const SaHpiAnnunciatorRecT *annrec, int offsets);static SaErrorT oh_build_event(oh_big_textbuffer *buffer, const SaHpiEventT *event, int offsets);static SaErrorT oh_build_event_resource(oh_big_textbuffer *buffer, const SaHpiEventT *event, int offsets);static SaErrorT oh_build_event_domain(oh_big_textbuffer *buffer, const SaHpiEventT *event, int offsets);static SaErrorT oh_build_event_sensor(oh_big_textbuffer *buffer, const SaHpiEventT *event, int offsets);static SaErrorT oh_build_event_sensor_enable_change(oh_big_textbuffer *buffer, const SaHpiEventT *event, int offsets);static SaErrorT oh_build_event_hotswap(oh_big_textbuffer *buffer, const SaHpiEventT *event, int offsets);static SaErrorT oh_build_event_watchdog(oh_big_textbuffer *buffer, const SaHpiEventT *event, int offsets);static SaErrorT oh_build_event_hpi_sw(oh_big_textbuffer *buffer, const SaHpiEventT *event, int offsets);static SaErrorT oh_build_event_oem(oh_big_textbuffer *buffer, const SaHpiEventT *event, int offsets);static SaErrorT oh_build_event_user(oh_big_textbuffer *buffer, const SaHpiEventT *event, int offsets);/************************************************************************ * NOTES! * * - Several error checks can be removed if valid_xxx routines are defined * for input structures. If this happens, several of the default switch * statements should also return SA_ERR_HPI_INTERNAL_ERROR instead * of SA_ERR_HPI_INVALID_PARMS. ************************************************************************//** * oh_lookup_manufacturerid: * @value: enum value of type SaHpiManufacturerIdT. * @buffer: Location to store the string. * * Converts @value into a string based on @value's enum definition * in http://www.iana.org/assignments/enterprise-numbers. * String is stored in an SaHpiTextBufferT data structure. * * Only a few of the manufacturers in that list have been defined. * For all others, this routine returns "Unknown Manufacturer". * Feel free to add your own favorite manufacturer to this routine. * * Returns: * SA_OK - normal operation. * SA_ERR_HPI_INVALID_PARAMS - @buffer is NULL. **/SaErrorT oh_decode_manufacturerid(SaHpiManufacturerIdT value, SaHpiTextBufferT *buffer) { SaErrorT err; SaHpiTextBufferT working; if (!buffer) { return(SA_ERR_HPI_INVALID_PARAMS); } err = oh_init_textbuffer(&working); if (err) { return(err); } switch(value) { case SAHPI_MANUFACTURER_ID_UNSPECIFIED: err = oh_append_textbuffer(&working, "UNSPECIFIED Manufacturer"); if (err) { return(err); } break; case 2: err = oh_append_textbuffer(&working,"IBM"); if (err) { return(err); } break; default: err = oh_append_textbuffer(&working, "Unknown Manufacturer"); if (err) { return(err); } } oh_copy_textbuffer(buffer, &working); return(SA_OK);}/** * oh_decode_sensorreading: * @reading: SaHpiSensorReadingT to convert. * @format: SaHpiDataFormatT for the sensor reading. * @buffer: Location to store the converted string. * * Converts an HPI sensor reading and format into a string. * String is stored in an SaHpiTextBufferT data structure. * * Returns: * SA_OK - normal operation. * SA_ERR_HPI_INVALID_CMD - @format or @reading have IsSupported == FALSE. * SA_ERR_HPI_INVALID_DATA - @format and @reading types don't match. * SA_ERR_HPI_INVALID_PARAMS - Pointer parameter(s) are NULL; @reading type != @format type. * SA_ERR_HPI_OUT_OF_SPACE - @buffer not big enough to accomodate appended string **/SaErrorT oh_decode_sensorreading(SaHpiSensorReadingT reading, SaHpiSensorDataFormatT format, SaHpiTextBufferT *buffer){ SaErrorT err; SaHpiTextBufferT working; char text[SAHPI_MAX_TEXT_BUFFER_LENGTH]; char str[SAHPI_SENSOR_BUFFER_LENGTH + 1]; if (!buffer) { return(SA_ERR_HPI_INVALID_PARAMS); } if (!reading.IsSupported || !format.IsSupported) { return(SA_ERR_HPI_INVALID_CMD); } if (reading.Type != format.ReadingType) { /* Check for special case */ if (!( (reading.Type == SAHPI_SENSOR_READING_TYPE_BUFFER) && ((strncmp(reading.Value.SensorBuffer,"(No temperature)", sizeof("(No temperature)")) == 0) || (strncmp(reading.Value.SensorBuffer,"Not Readable!", sizeof("Not Readable!")) == 0)) )) return(SA_ERR_HPI_INVALID_DATA); } oh_init_textbuffer(&working); memset(text, 0, SAHPI_MAX_TEXT_BUFFER_LENGTH); switch(reading.Type) { case SAHPI_SENSOR_READING_TYPE_INT64: snprintf(text, SAHPI_MAX_TEXT_BUFFER_LENGTH, "%lld", reading.Value.SensorInt64); err = oh_append_textbuffer(&working, text); if (err) { return(err); } break; case SAHPI_SENSOR_READING_TYPE_UINT64: snprintf(text, SAHPI_MAX_TEXT_BUFFER_LENGTH, "%llu", reading.Value.SensorUint64); err = oh_append_textbuffer(&working, text); if (err) { return(err); } break; case SAHPI_SENSOR_READING_TYPE_FLOAT64: snprintf(text, SAHPI_MAX_TEXT_BUFFER_LENGTH, "%le", reading.Value.SensorFloat64); err = oh_append_textbuffer(&working, text); if (err) { return(err); } break; case SAHPI_SENSOR_READING_TYPE_BUFFER: /* In case Sensor Buffer contains no end of string deliminter */ memset(str, 0, SAHPI_SENSOR_BUFFER_LENGTH + 1); strncpy(str, reading.Value.SensorBuffer, SAHPI_SENSOR_BUFFER_LENGTH); err = oh_append_textbuffer(&working, str); if (err) { return(err); } break; default: return(SA_ERR_HPI_INVALID_PARAMS); } if (format.Percentage) { err = oh_append_textbuffer(&working, "%"); if (err) { return(err); } } else { /* Add units */ if (format.BaseUnits != SAHPI_SU_UNSPECIFIED) { const char *str; err = oh_append_textbuffer(&working, " "); if (err) { return(err); } str = oh_lookup_sensorunits(format.BaseUnits); if (str == NULL) { return(SA_ERR_HPI_INVALID_PARAMS); } err = oh_append_textbuffer(&working, str); if (err) { return(err); } } /* Add modifier units, if appropriate */ if (format.BaseUnits != SAHPI_SU_UNSPECIFIED && format.ModifierUse != SAHPI_SMUU_NONE) { const char *str; switch(format.ModifierUse) { case SAHPI_SMUU_BASIC_OVER_MODIFIER: err = oh_append_textbuffer(&working, " / "); if (err) { return(err); } break; case SAHPI_SMUU_BASIC_TIMES_MODIFIER: err = oh_append_textbuffer(&working, " * "); if (err) { return(err); } break; default: return(SA_ERR_HPI_INVALID_PARAMS); } str = oh_lookup_sensorunits(format.ModifierUnits); if (str == NULL) { return(SA_ERR_HPI_INVALID_PARAMS); } err = oh_append_textbuffer(&working, str); if (err) { return(err); } } } oh_copy_textbuffer(buffer, &working); return(SA_OK);}/** * oh_encode_sensorreading: * @buffer: Location of SaHpiTextBufferT containing the string to * convert into a SaHpiSensorReadingT. * @type: SaHpiSensorReadingTypeT of converted reading. * @reading: SaHpiSensorReadingT location to store converted string. * * Converts @buffer->Data string to an HPI SaHpiSensorReadingT structure. * Generally @buffer->Data is created by oh_decode_sensorreading() or has * been built by a plugin, which gets string values for sensor readings (e.g. * through SNMP OID commands). Any non-numeric portion of the string is * discarded. For example, the string "-1.43 Volts" is converted to -1.43 * of type @type. * * If type = SAHPI_SENSOR_READING_TYPE_BUFFER, and @buffer->Data > * SAHPI_SENSOR_BUFFER_LENGTH, data is truncated to fit into the reading * buffer. * * Notes! * - Numerical strings can contain commas but it is assummed that strings follow * US format (e.g. "1,000,000" = 1 million; not "1.000.000"). * - Decimal points are always preceded by at least one number (e.g. "0.9") * - Numerical percentage strings like "9%" are converted into a float 0.09 * - Hex notation is not supported (e.g. "0x23") * - Scientific notation is not supported (e.g. "e+02"). * * Returns: * SA_OK - normal operation. * SA_ERR_HPI_INVALID_PARAMS - Pointer parameter(s) are NULL; Invalid @type. * SA_ERR_HPI_INVALID_DATA - Converted @buffer->Data too large for @type; cannot * convert string into valid number; @type incorrect * for resulting number (e.g. percentage not a float). **/SaErrorT oh_encode_sensorreading(SaHpiTextBufferT *buffer, SaHpiSensorReadingTypeT type, SaHpiSensorReadingT *reading){ char numstr[SAHPI_MAX_TEXT_BUFFER_LENGTH]; char *endptr; int i, j; int found_sign, found_number, found_float, in_number; int is_percent = 0; SaHpiFloat64T num_float64 = 0.0; SaHpiInt64T num_int64 = 0; SaHpiUint64T num_uint64 = 0; SaHpiSensorReadingT working; if (!buffer || !reading || buffer->Data == NULL || buffer->Data[0] == '\0' || !oh_lookup_sensorreadingtype(type)) { return(SA_ERR_HPI_INVALID_PARAMS); } if (type == SAHPI_SENSOR_READING_TYPE_BUFFER) { reading->IsSupported = SAHPI_TRUE; reading->Type = type; strncpy(reading->Value.SensorBuffer, buffer->Data, SAHPI_SENSOR_BUFFER_LENGTH); return(SA_OK); } memset(numstr, 0, SAHPI_MAX_TEXT_BUFFER_LENGTH); memset(&working, 0, sizeof(SaHpiSensorReadingT)); working.IsSupported = SAHPI_TRUE; working.Type = type; /* Search string and pull out first numeric string. * The strtol type functions below are pretty good at handling * non-numeric junk in string, but they don't handle spaces * after a sign or commas within a number. * So we normalize the string a bit first. */ j = found_sign = in_number = found_number = found_float = 0; for (i=0; i<buffer->DataLength && !found_number; i++) { if (buffer->Data[i] == '+' || buffer->Data[i] == '-') { if (found_sign) { dbg("Cannot parse multiple sign values"); return(SA_ERR_HPI_INVALID_DATA); } found_sign = 1; numstr[j] = buffer->Data[i]; j++; } if (isdigit(buffer->Data[i])) { if (!found_number) { in_number = 1; numstr[j] = buffer->Data[i]; j++; } } else { /* Strip non-numerics */ if (buffer->Data[i] == '.') { /* Unless its a decimal point */ if (in_number) { if (found_float) { dbg("Cannot parse multiple decimal points"); return(SA_ERR_HPI_INVALID_DATA); } found_float = 1; numstr[j] = buffer->Data[i]; j++; } } else { /* Delete commas but don't end search for more numbers */ if (in_number && buffer->Data[i] != ',') { found_number = 1; } } } } if (found_number || in_number) { /* in_number means string ended in a digit character */ for (j=i-1; j<buffer->DataLength; j++) { if (buffer->Data[j] == '%') { is_percent = 1; break; } } found_number = 1; } if ((is_percent || found_float) && type != SAHPI_SENSOR_READING_TYPE_FLOAT64) { dbg("Number and type incompatible"); return(SA_ERR_HPI_INVALID_DATA); } /* Convert string to number */ switch (type) { case SAHPI_SENSOR_READING_TYPE_INT64: if (found_number) { errno = 0; num_int64 = strtoll(numstr, &endptr, 10); if (errno) { dbg("strtoll failed, errno=%d", errno); return(SA_ERR_HPI_INVALID_DATA); } if (*endptr != '\0') { dbg("strtoll failed: End Pointer=%s", endptr); return(SA_ERR_HPI_INVALID_DATA); } } else { /* No number in string */ num_int64 = 0; } working.Value.SensorInt64 = num_int64; break; case SAHPI_SENSOR_READING_TYPE_UINT64: if (found_number) { errno = 0; num_uint64 = strtoull(numstr, &endptr, 10); if (errno) { dbg("strtoull failed, errno=%d", errno); return(SA_ERR_HPI_INVALID_DATA); } if (*endptr != '\0') { dbg("strtoull failed: End Pointer=%s", endptr); return(SA_ERR_HPI_INVALID_DATA); } } else { /* No number in string */ num_uint64 = 0; } working.Value.SensorUint64 = num_uint64; break; case SAHPI_SENSOR_READING_TYPE_FLOAT64: if (found_number) { errno = 0; num_float64 = strtold(numstr, &endptr); if (errno) { dbg("strtold failed, errno=%d", errno); return(SA_ERR_HPI_INVALID_DATA); } if (*endptr != '\0') { dbg("strtold failed: End Pointer=%s", endptr); return(SA_ERR_HPI_INVALID_DATA); } if (is_percent) { working.Value.SensorFloat64 = num_float64/100.0; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -