480 lines
18 KiB
C
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 */
|