Unraid-SlackPack/source/freeipmi/usr/include/freeipmi/sel/ipmi-sel.h
2016-03-24 14:02:30 -06:00

480 lines
18 KiB
C

/*
* Copyright (C) 2003-2015 FreeIPMI Core Team
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef IPMI_SEL_H
#define IPMI_SEL_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <freeipmi/api/ipmi-api.h>
#include <freeipmi/cmds/ipmi-sel-cmds.h>
#include <freeipmi/interpret/ipmi-interpret.h>
#include <freeipmi/sdr/ipmi-sdr.h>
#define IPMI_SEL_ERR_SUCCESS 0
#define IPMI_SEL_ERR_CONTEXT_NULL 1
#define IPMI_SEL_ERR_CONTEXT_INVALID 2
#define IPMI_SEL_ERR_PARAMETERS 3
#define IPMI_SEL_ERR_OUT_OF_MEMORY 4
#define IPMI_SEL_ERR_SDR_CACHE_ERROR 5
#define IPMI_SEL_ERR_SEL_ENTRIES_NOT_LOADED 6
#define IPMI_SEL_ERR_NO_SEL_ENTRIES 7
#define IPMI_SEL_ERR_SEL_ENTRIES_LIST_END 8
#define IPMI_SEL_ERR_INVALID_SEL_ENTRY 9
#define IPMI_SEL_ERR_NOT_FOUND 10
#define IPMI_SEL_ERR_RESERVATION_CANCELED 11
#define IPMI_SEL_ERR_INTERPRET_ERROR 12
#define IPMI_SEL_ERR_CALLBACK_ERROR 13
#define IPMI_SEL_ERR_IPMI_ERROR 14
#define IPMI_SEL_ERR_SYSTEM_ERROR 15
#define IPMI_SEL_ERR_OVERFLOW 16
#define IPMI_SEL_ERR_INTERNAL_ERROR 17
#define IPMI_SEL_ERR_ERRNUMRANGE 18
#define IPMI_SEL_FLAGS_DEFAULT 0x0000
#define IPMI_SEL_FLAGS_DEBUG_DUMP 0x0001
#define IPMI_SEL_FLAGS_ASSUME_SYTEM_EVENT_RECORDS 0x0002
#define IPMI_SEL_PARAMETER_INTERPRET_CONTEXT 0x0001
#define IPMI_SEL_PARAMETER_UTC_OFFSET 0x0002
#define IPMI_SEL_STRING_FLAGS_DEFAULT 0x0000
#define IPMI_SEL_STRING_FLAGS_VERBOSE 0x0001
#define IPMI_SEL_STRING_FLAGS_IGNORE_UNAVAILABLE_FIELD 0x0002
#define IPMI_SEL_STRING_FLAGS_OUTPUT_NOT_AVAILABLE 0x0004
#define IPMI_SEL_STRING_FLAGS_DATE_USE_SLASH 0x0008
#define IPMI_SEL_STRING_FLAGS_DATE_MONTH_STRING 0x0010
#define IPMI_SEL_STRING_FLAGS_NON_ABBREVIATED_UNITS 0x0020
#define IPMI_SEL_STRING_FLAGS_ENTITY_SENSOR_NAMES 0x0040
#define IPMI_SEL_STRING_FLAGS_INTERPRET_OEM_DATA 0x0100
/* Timestamps are defined as localtime. If there are UTC and
* one wishes to output in localtime, this flag will do so.
*/
#define IPMI_SEL_STRING_FLAGS_UTC_TO_LOCALTIME 0x0200
/* Convert localtimes to UTC times, as it may be convenient
* for certain purposes.
*/
#define IPMI_SEL_STRING_FLAGS_LOCALTIME_TO_UTC 0x0400
#define IPMI_SEL_STRING_FLAGS_LEGACY 0x1000
#define IPMI_SEL_RECORD_TYPE_CLASS_SYSTEM_EVENT_RECORD 0x0
#define IPMI_SEL_RECORD_TYPE_CLASS_TIMESTAMPED_OEM_RECORD 0x1
#define IPMI_SEL_RECORD_TYPE_CLASS_NON_TIMESTAMPED_OEM_RECORD 0x2
#define IPMI_SEL_RECORD_TYPE_CLASS_UNKNOWN 0x3
#define IPMI_SEL_RECORD_ID_FIRST IPMI_SEL_GET_RECORD_ID_FIRST_ENTRY
#define IPMI_SEL_RECORD_ID_LAST IPMI_SEL_GET_RECORD_ID_LAST_ENTRY
typedef struct ipmi_sel_ctx *ipmi_sel_ctx_t;
typedef int (*Ipmi_Sel_Parse_Callback)(ipmi_sel_ctx_t ctx, void *callback_data);
/*
* SEL Context Functions
*/
/* ipmi_sel_ctx_create
* - if specified, ipmi_ctx must be open and ready to go
* - if NULL ipmi_ctx, SEL ctx cannot be used for SEL reading, only parsing records
* - if specified, sdr_ctx cache must be open and ready for reading
* - if NULL sdr_ctx, sdr won't be used
*/
ipmi_sel_ctx_t ipmi_sel_ctx_create (ipmi_ctx_t ipmi_ctx, ipmi_sdr_ctx_t sdr_ctx);
void ipmi_sel_ctx_destroy (ipmi_sel_ctx_t ctx);
int ipmi_sel_ctx_errnum (ipmi_sel_ctx_t ctx);
char * ipmi_sel_ctx_strerror (int errnum);
char * ipmi_sel_ctx_errormsg (ipmi_sel_ctx_t ctx);
/* SEL Parse flag functions and settings functions */
int ipmi_sel_ctx_get_flags (ipmi_sel_ctx_t ctx, unsigned int *flags);
int ipmi_sel_ctx_set_flags (ipmi_sel_ctx_t ctx, unsigned int flags);
/* for use w/ string parsing w/ IPMI_SEL_STRING_FLAGS_INTERPRET_OEM_DATA */
int ipmi_sel_ctx_get_manufacturer_id (ipmi_sel_ctx_t ctx, uint32_t *manufacturer_id);
int ipmi_sel_ctx_set_manufacturer_id (ipmi_sel_ctx_t ctx, uint32_t manufacturer_id);
int ipmi_sel_ctx_get_product_id (ipmi_sel_ctx_t ctx, uint16_t *product_id);
int ipmi_sel_ctx_set_product_id (ipmi_sel_ctx_t ctx, uint16_t product_id);
int ipmi_sel_ctx_get_ipmi_version (ipmi_sel_ctx_t ctx,
uint8_t *ipmi_version_major,
uint8_t *ipmi_vesion_minor);
int ipmi_sel_ctx_set_ipmi_version (ipmi_sel_ctx_t ctx,
uint8_t ipmi_version_major,
uint8_t ipmi_version_minor);
/* get/set parameters
*
* For misc uses.
*
* INTERPRET_CONTEXT - for use with %I - see below. interpret_ctx
* assumed loaded with whatever config desired for interpretation
*
* UTC_OFFSET - specific UTC offset to apply to timestamps (int)
*/
int ipmi_sel_ctx_get_parameter (ipmi_sel_ctx_t ctx,
unsigned int parameter,
void *ptr);
/* Pass NULL as ptr for default value */
int ipmi_sel_ctx_set_parameter (ipmi_sel_ctx_t ctx,
unsigned int parameter,
const void *ptr);
char *ipmi_sel_ctx_get_debug_prefix (ipmi_sel_ctx_t ctx);
int ipmi_sel_ctx_set_debug_prefix (ipmi_sel_ctx_t ctx, const char *debug_prefix);
/* determines separator between fields in string functions
*
* defaults to " | "
*/
char *ipmi_sel_ctx_get_separator (ipmi_sel_ctx_t ctx);
int ipmi_sel_ctx_set_separator (ipmi_sel_ctx_t ctx, const char *separator);
/* register/clear a reservation ID
* - Almost all SEL operations use a reservation ID. Generally
* speaking, it can be considered an advisory lock. The same
* reservation ID can be used for all "read" operations and will only
* be canceled when some "write" operation has occurred on the SEL.
* This "write" operation could be a new SEL event, a SEL event that
* was deleted, etc.
* - Normally, it is no big deal for a reservation ID to be canceled.
* The most normal circumstance is a new SEL event has been generated
* while reading the current list of SEL records. Therefore, under
* most circumstances, this library will simple re-retrieve a
* reservation ID once it has noticed one has been canceled.
* - These functions allow you to override the default functionality.
* You may inform the library to register a specific reservation ID
* and continue to use it for all SEL operations. In the event that
* it has been canceled, a IPMI_SEL_ERR_RESERVATION_CANCELED
* errnum will be returned.
* - These functions are predominantly useful for doing a set of
* operations and wanting to be informed of a possible race
* condition occurring. For example, perhaps you wish to read all
* the SEL records, log them, then clear them. There is a small
* window where a new SEL event could be generated, then cleared
* without the user knowing it ever existed. Use of a fixed
* reservation ID would be a mechanism to notice this.
* - In the event a reservation ID is canceled, it is up to the user
* to re-register a reservation ID, otherwise SEL operations will
* continue to default to grab its own reservation ID.
* - In ipmi_sel_ctx_register_reservation_id(), an optional
* reservation_id can be passed to see what reservation ID was
* specifically registered.
*/
int ipmi_sel_ctx_register_reservation_id (ipmi_sel_ctx_t ctx, uint16_t *reservation_id);
int ipmi_sel_ctx_clear_reservation_id (ipmi_sel_ctx_t ctx);
/*
* SEL Parse Functions
*/
/* ipmi_sel_parse and ipmi_sel_parse_record_ids
* - callback is called after each SEL entry is parsed
* - Returns the number of entries parsed
*/
int ipmi_sel_parse (ipmi_sel_ctx_t ctx,
uint16_t record_id_start,
uint16_t record_id_last,
Ipmi_Sel_Parse_Callback callback,
void *callback_data);
int ipmi_sel_parse_record_ids (ipmi_sel_ctx_t ctx,
uint16_t *record_ids,
unsigned int record_ids_len,
Ipmi_Sel_Parse_Callback callback,
void *callback_data);
/* SEL data retrieval functions after SEL is parsed
*
* seek_record_id moves the iterator to the closest record_id >= record_id
* search_record_id finds the record id, will return NOT_FOUND if it can't be found
*/
int ipmi_sel_parse_first (ipmi_sel_ctx_t ctx);
int ipmi_sel_parse_next (ipmi_sel_ctx_t ctx);
int ipmi_sel_parse_sel_entry_count (ipmi_sel_ctx_t ctx);
int ipmi_sel_parse_seek_record_id (ipmi_sel_ctx_t ctx, uint16_t record_id);
int ipmi_sel_parse_search_record_id (ipmi_sel_ctx_t ctx, uint16_t record_id);
/* return length of data read into buffer on success, -1 on error */
int ipmi_sel_parse_read_record (ipmi_sel_ctx_t ctx,
void *buf,
unsigned int buflen);
/* SEL record parsing functions
*
* - if a sel_record is passed in, that sel_record is used for
* reading/parsing
*
* - if the sel_record is NULL sel_record_len is 0, the current sel
* parsed after ipmi_sel_parse() or ipmi_sel_parse_record_ids() is
* used. It can be the record used within the iterator functions
* (i.e. ipmi_sel_parse_next()) or in callbacks.
*
* - will return IPMI_SEL_ERR_INVALID_SEL_ENTRY if current sel
* entry is not appropriate for data requested.
*/
/* record_id & record_type - works with all SEL record types */
int ipmi_sel_parse_read_record_id (ipmi_sel_ctx_t ctx,
const void *sel_record,
unsigned int sel_record_len,
uint16_t *record_id);
int ipmi_sel_parse_read_record_type (ipmi_sel_ctx_t ctx,
const void *sel_record,
unsigned int sel_record_len,
uint8_t *record_type);
/* timetamp - works with sel event and timestamped OEM record types */
int ipmi_sel_parse_read_timestamp (ipmi_sel_ctx_t ctx,
const void *sel_record,
unsigned int sel_record_len,
uint32_t *timestamp);
/* generator_id, event message format version, sensor type, sensor
* number, event direction, event type code, and event data available
* form system event record type
*/
int ipmi_sel_parse_read_generator_id (ipmi_sel_ctx_t ctx,
const void *sel_record,
unsigned int sel_record_len,
uint8_t *generator_id);
int ipmi_sel_parse_read_ipmb_device_lun (ipmi_sel_ctx_t ctx,
const void *sel_record,
unsigned int sel_record_len,
uint8_t *ipmb_device_lun);
int ipmi_sel_parse_read_channel_number (ipmi_sel_ctx_t ctx,
const void *sel_record,
unsigned int sel_record_len,
uint8_t *channel_number);
int ipmi_sel_parse_read_event_message_format_version (ipmi_sel_ctx_t ctx,
const void *sel_record,
unsigned int sel_record_len,
uint8_t *event_message_format_version);
int ipmi_sel_parse_read_sensor_type (ipmi_sel_ctx_t ctx,
const void *sel_record,
unsigned int sel_record_len,
uint8_t *sensor_type);
int ipmi_sel_parse_read_sensor_number (ipmi_sel_ctx_t ctx,
const void *sel_record,
unsigned int sel_record_len,
uint8_t *sensor_number);
int ipmi_sel_parse_read_event_direction (ipmi_sel_ctx_t ctx,
const void *sel_record,
unsigned int sel_record_len,
uint8_t *event_direction);
int ipmi_sel_parse_read_event_type_code (ipmi_sel_ctx_t ctx,
const void *sel_record,
unsigned int sel_record_len,
uint8_t *event_type_code);
int ipmi_sel_parse_read_event_data1 (ipmi_sel_ctx_t ctx,
const void *sel_record,
unsigned int sel_record_len,
uint8_t *event_data1);
int ipmi_sel_parse_read_event_data1_offset_from_event_reading_type_code (ipmi_sel_ctx_t ctx,
const void *sel_record,
unsigned int sel_record_len,
uint8_t *event_data1_offset);
int ipmi_sel_parse_read_event_data1_event_data2_flag (ipmi_sel_ctx_t ctx,
const void *sel_record,
unsigned int sel_record_len,
uint8_t *event_data2_flag);
int ipmi_sel_parse_read_event_data1_event_data3_flag (ipmi_sel_ctx_t ctx,
const void *sel_record,
unsigned int sel_record_len,
uint8_t *event_data3_flag);
int ipmi_sel_parse_read_event_data2 (ipmi_sel_ctx_t ctx,
const void *sel_record,
unsigned int sel_record_len,
uint8_t *event_data2);
int ipmi_sel_parse_read_event_data3 (ipmi_sel_ctx_t ctx,
const void *sel_record,
unsigned int sel_record_len,
uint8_t *event_data3);
/* manufacturer_id - works with sel timestamped OEM record types */
int ipmi_sel_parse_read_manufacturer_id (ipmi_sel_ctx_t ctx,
const void *sel_record,
unsigned int sel_record_len,
uint32_t *manufacturer_id);
/* oem - works with sel timestamped and non-timestamped OEM record types */
/* return length of data read into buffer on success, -1 on error */
int ipmi_sel_parse_read_oem (ipmi_sel_ctx_t ctx,
const void *sel_record,
unsigned int sel_record_len,
void *buf,
unsigned int buflen);
/*
* create a string output of the SEL entry.
*
* String format - availability for output dependent on SEL record
* type.
*
* Available in all SEL record types
*
* %i - record ID in decimal
* %I - event nominal vs. warning vs. critical interpretation [1]
*
* [1] - see libfreeipmi interpret library for information. See
* ipmi_sel_ctx_set_interpret_ctx(). If interpret context not
* available, returns INTERPRET_ERROR.
*
* Available in SEL event and timestamped OEM SEL records
*
* %t - time in format H:M:S using 24 hour clock
* %d - date in format D-M-YEAR
*
* Available in SEL event records
*
* %T - sensor type
* %s - sensor name
* %e - event data 1 string (usually offset from event/reading code type string)
* %f - event data 2 string [2]
* %h - event data 3 string
* %c - combined event data 2 and event data 3 string [3]
* %p - event data 2 previous state string [4]
* %S - event data 2 severity string [4]
* %E - combined event data 1, 2, and 3 string [5]
* %k - event direction
*
* [2] - if a previous state and a severity state string are available
* from a discrete sensor, they are concatenated with the defined
* separator in between.
*
* [3] - for events where both event data 2 and event data 3 hold data
* that must be combined for an effective output. As an example, data
* 2 holds a minor version number and data 3 holds a major version
* number. The combined output might print out "Version 1.2" instead
* of a separated "Major Version 1 ; Minor Version 2" if you did them
* separately. If a combined output is not available or not
* reasonable, event data 2 and event data 3 output will be output
* separately with the defined separator between them
* (e.g. effectively "%f ; %h").
*
* [4] - if event type code indicates a discrete sensor and event data 2
* flag indicates a previous state and/or severity state is available.
*
* [5] - this can be loosely considered the equivalent of "%e" and
* "%c" concatenated with the defined separator between them.
* However, various corner cases will be handled for the user to
* create a nicer output. For example, "Foo ; NA" will never be
* output. This will be condensed into just "Foo".
*
* Available in timestamped OEM SEL records
*
* %m - manufacturer id
*
* Available in SEL timestamped and non-timestamped OEM record types
*
* %o - oem data in hex (or strings if interpreted OEM available)
*
* Available in all record types for certain manufacturers
*
* %O - output an OEM supplied string describing the event. [6]
*
* [6] On some motherboards, the vendor is capable of supplying a full
* string describing the event data, in particular supplying strings
* for OEM records and OEM event extensions. Under the right
* conditions, this output option may be used as a potential
* replacement for %e, %f, %h, %c, and/or %E. If an OEM supplied string
* is not available, nothing will be output (with the exception of N/A
* if the OUTPUT_NOT_AVAILABLE flag is set). Currently, this output
* option supports Fujitsu systems with iRMC S1/iRMC S2.
*
* Misc
*
* %% - percent sign
*
* flags
*
* VERBOSE
*
* Output slightly more verbose text for selected fields. For example:
*
* - If a sensor does not have a name, output sensor number and
* generator id instead of just sensor number.
* - If an event data string cannot be determined (i.e. it is OEM or
* not defined by IPMI), output both the data and event type code
* instead of just the event data.
*
* IGNORE_UNAVAILABLE_FIELD
*
* If a field is not available for output (for example, a timestamp field
* in a SEL entry w/o a timestamp field), do not return an error. Output
* nothing.
*
* OUTPUT_NOT_AVAILABLE
*
* If a field is not available, do not output an empty string, output
* "N/A" (sometimes must have IGNORE_UNAVAILABLE_FIELD set)
*
* DATE_USE_SLASH
*
* Use a '/' instead of hyphens when outputting the date.
*
* DATE_MONTH_STRING
*
* Output a month name (Jan, Feb, Mar, etc.) instead of the month
* number when outputting the date.
*
* LEGACY
*
* Output strings in legacy format.
*
* Returns length of data written to buffer. If >= buflen, no null
* termination exists in buffer.
*/
int ipmi_sel_parse_read_record_string (ipmi_sel_ctx_t ctx,
const char *fmt,
const void *sel_record,
unsigned int sel_record_len,
char *buf,
unsigned int buflen,
unsigned int flags);
/*
* SEL Utility functions
*/
int ipmi_sel_clear_sel (ipmi_sel_ctx_t ctx);
int ipmi_sel_delete_sel_entry (ipmi_sel_ctx_t ctx, uint16_t record_id);
int ipmi_sel_record_type_class (uint8_t record_type);
#ifdef __cplusplus
}
#endif
#endif /* IPMI_SEL_H */