diff options
Diffstat (limited to 'lib/ipmi_event.c')
-rw-r--r-- | lib/ipmi_event.c | 184 |
1 files changed, 82 insertions, 102 deletions
diff --git a/lib/ipmi_event.c b/lib/ipmi_event.c index bc32ae8..df6aa51 100644 --- a/lib/ipmi_event.c +++ b/lib/ipmi_event.c @@ -29,7 +29,6 @@ * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. */ -#define _BSD_SOURCE #include <stdlib.h> #include <stdio.h> @@ -53,6 +52,14 @@ #include <ipmitool/ipmi_event.h> #include <ipmitool/ipmi_sdr.h> +static +inline +bool +is_system(const struct channel_info_t *chinfo) +{ + return (IPMI_CHANNEL_MEDIUM_SYSTEM == chinfo->medium + || CH_SYSTEM == chinfo->channel); +} static void ipmi_event_msg_print(struct ipmi_intf * intf, struct platform_event_msg * pmsg) @@ -62,7 +69,8 @@ ipmi_event_msg_print(struct ipmi_intf * intf, struct platform_event_msg * pmsg) memset(&sel_event, 0, sizeof(struct sel_event_record)); sel_event.record_id = 0; - sel_event.sel_type.standard_type.gen_id = 2; + htoipmi16(EVENT_GENERATOR(SMS, 0), + (void *)&sel_event.sel_type.standard_type.gen_id); sel_event.sel_type.standard_type.evm_rev = pmsg->evm_rev; sel_event.sel_type.standard_type.sensor_type = pmsg->sensor_type; @@ -84,36 +92,42 @@ ipmi_send_platform_event(struct ipmi_intf * intf, struct platform_event_msg * em { struct ipmi_rs * rsp; struct ipmi_rq req; - uint8_t rqdata[8]; - uint8_t chmed; + uint8_t rqdata[PLATFORM_EVENT_DATA_LEN_MAX]; + uint8_t *rqdata_start = rqdata; + struct channel_info_t chinfo; memset(&req, 0, sizeof(req)); - memset(rqdata, 0, 8); + memset(rqdata, 0, sizeof(rqdata)); req.msg.netfn = IPMI_NETFN_SE; - req.msg.cmd = 0x02; + req.msg.cmd = IPMI_CMD_PLATFORM_EVENT; req.msg.data = rqdata; + req.msg.data_len = PLATFORM_EVENT_DATA_LEN_NON_SI; - chmed = ipmi_current_channel_medium(intf); - if (chmed == IPMI_CHANNEL_MEDIUM_SYSTEM) { - /* system interface, need extra generator ID */ - req.msg.data_len = 8; - rqdata[0] = 0x41; // As per Fig. 29-2 and Table 5-4 - memcpy(rqdata+1, emsg, sizeof(struct platform_event_msg)); + ipmi_current_channel_info(intf, &chinfo); + if (chinfo.channel == CH_UNKNOWN) { + lprintf(LOG_ERR, "Failed to send the platform event " + "via an unknown channel"); + return -3; } - else { - req.msg.data_len = 7; - memcpy(rqdata, emsg, sizeof(struct platform_event_msg)); + + if (is_system(&chinfo)) { + /* system interface, need extra generator ID, see Fig. 29-2 */ + req.msg.data_len = PLATFORM_EVENT_DATA_LEN_SI; + rqdata[0] = EVENT_GENERATOR(SMS, 0); + rqdata_start++; } + memcpy(rqdata_start, emsg, sizeof(struct platform_event_msg)); + ipmi_event_msg_print(intf, emsg); rsp = intf->sendrecv(intf, &req); - if (rsp == NULL) { + if (!rsp) { lprintf(LOG_ERR, "Platform Event Message command failed"); return -1; } - else if (rsp->ccode > 0) { + else if (rsp->ccode) { lprintf(LOG_ERR, "Platform Event Message command failed: %s", val2str(rsp->ccode, completion_code_vals)); return -1; @@ -211,14 +225,14 @@ ipmi_event_find_offset(struct ipmi_intf *intf, uint8_t sensor_type, uint8_t even { const struct ipmi_event_sensor_types *evt; - if (desc == NULL || sensor_type == 0 || event_type == 0) { + if (!desc || sensor_type == 0 || event_type == 0) { return 0x00; } for (evt = ipmi_get_first_event_sensor_type(intf, sensor_type, event_type); - evt != NULL; evt = ipmi_get_next_event_sensor_type(evt)) { - if (evt->desc != NULL && - strncasecmp(desc, evt->desc, __maxlen(desc, evt->desc)) == 0) { + evt; evt = ipmi_get_next_event_sensor_type(evt)) { + if (evt->desc && + strcasecmp(desc, evt->desc) == 0) { return evt->offset; } } @@ -246,7 +260,7 @@ ipmi_event_fromsensor(struct ipmi_intf * intf, char * id, char * state, char * e int off; uint8_t target, lun, channel; - if (id == NULL) { + if (!id) { lprintf(LOG_ERR, "No sensor ID supplied"); return -1; } @@ -254,11 +268,11 @@ ipmi_event_fromsensor(struct ipmi_intf * intf, char * id, char * state, char * e memset(&emsg, 0, sizeof(struct platform_event_msg)); emsg.evm_rev = 0x04; - if (evdir == NULL) + if (!evdir) emsg.event_dir = EVENT_DIR_ASSERT; - else if (strncasecmp(evdir, "assert", 6) == 0) + else if (!strcmp(evdir, "assert")) emsg.event_dir = EVENT_DIR_ASSERT; - else if (strncasecmp(evdir, "deassert", 8) == 0) + else if (!strcmp(evdir, "deassert")) emsg.event_dir = EVENT_DIR_DEASSERT; else { lprintf(LOG_ERR, "Invalid event direction %s. Must be 'assert' or 'deassert'", evdir); @@ -267,7 +281,7 @@ ipmi_event_fromsensor(struct ipmi_intf * intf, char * id, char * state, char * e printf("Finding sensor %s... ", id); sdr = ipmi_sdr_find_sdr_byid(intf, id); - if (sdr == NULL) { + if (!sdr) { printf("not found!\n"); return -1; } @@ -304,7 +318,7 @@ ipmi_event_fromsensor(struct ipmi_intf * intf, char * id, char * state, char * e int hilo = 0; off = 1; - if (state == NULL || strncasecmp(state, "list", 4) == 0) { + if (!state || !strcmp(state, "list")) { printf("Sensor States:\n"); printf(" lnr : Lower Non-Recoverable \n"); printf(" lcr : Lower Critical\n"); @@ -315,12 +329,12 @@ ipmi_event_fromsensor(struct ipmi_intf * intf, char * id, char * state, char * e return -1; } - if (0 != strncasecmp(state, "lnr", 3) && - 0 != strncasecmp(state, "lcr", 3) && - 0 != strncasecmp(state, "lnc", 3) && - 0 != strncasecmp(state, "unc", 3) && - 0 != strncasecmp(state, "ucr", 3) && - 0 != strncasecmp(state, "unr", 3)) + if (0 != strcmp(state, "lnr") && + 0 != strcmp(state, "lcr") && + 0 != strcmp(state, "lnc") && + 0 != strcmp(state, "unc") && + 0 != strcmp(state, "ucr") && + 0 != strcmp(state, "unr")) { lprintf(LOG_ERR, "Invalid threshold identifier %s", state); return -1; @@ -349,11 +363,11 @@ ipmi_event_fromsensor(struct ipmi_intf * intf, char * id, char * state, char * e rsp = ipmi_sdr_get_sensor_thresholds(intf, emsg.sensor_num, target, lun, channel); - if (rsp == NULL) { + if (!rsp) { lprintf(LOG_ERR, "Command Get Sensor Thresholds failed: invalid response."); return (-1); - } else if (rsp->ccode != 0) { + } else if (rsp->ccode) { lprintf(LOG_ERR, "Command Get Sensor Thresholds failed: %s", val2str(rsp->ccode, completion_code_vals)); return (-1); @@ -364,7 +378,7 @@ ipmi_event_fromsensor(struct ipmi_intf * intf, char * id, char * state, char * e rsp = ipmi_sdr_get_sensor_hysteresis(intf, emsg.sensor_num, target, lun, channel); - if (rsp != NULL && rsp->ccode == 0) + if (rsp && !rsp->ccode) off = dir ? rsp->data[0] : rsp->data[1]; if (off <= 0) off = 1; @@ -401,7 +415,7 @@ ipmi_event_fromsensor(struct ipmi_intf * intf, char * id, char * state, char * e /* * print list of available states for this sensor */ - if (state == NULL || strncasecmp(state, "list", 4) == 0) { + if (!state || strcasecmp(state, "list") == 0) { print_sensor_states(intf, emsg.sensor_type, emsg.event_type); printf("Sensor State Shortcuts:\n"); for (x = 0; x < sizeof(digi_on)/sizeof(*digi_on); x++) { @@ -412,12 +426,12 @@ ipmi_event_fromsensor(struct ipmi_intf * intf, char * id, char * state, char * e off = 0; for (x = 0; x < sizeof(digi_on)/sizeof(*digi_on); x++) { - if (strncasecmp(state, digi_on[x], strlen(digi_on[x])) == 0) { + if (strcasecmp(state, digi_on[x]) == 0) { emsg.event_data[0] = 1; off = 1; break; } - else if (strncasecmp(state, digi_off[x], strlen(digi_off[x])) == 0) { + else if (strcasecmp(state, digi_off[x]) == 0) { emsg.event_data[0] = 0; off = 1; break; @@ -441,7 +455,7 @@ ipmi_event_fromsensor(struct ipmi_intf * intf, char * id, char * state, char * e /* * print list of available states for this sensor */ - if (state == NULL || strncasecmp(state, "list", 4) == 0) { + if (!state || strcasecmp(state, "list") == 0) { print_sensor_states(intf, emsg.sensor_type, emsg.event_type); return 0; } @@ -461,7 +475,7 @@ ipmi_event_fromsensor(struct ipmi_intf * intf, char * id, char * state, char * e /* * print list of available states for this sensor */ - if (state == NULL || strncasecmp(state, "list", 4) == 0) { + if (!state || strcasecmp(state, "list") == 0) { print_sensor_states(intf, emsg.sensor_type, emsg.event_type); return 0; } @@ -485,43 +499,30 @@ static int ipmi_event_fromfile(struct ipmi_intf * intf, char * file) { FILE * fp; - struct ipmi_rs * rsp; - struct ipmi_rq req; - struct sel_event_record sel_event; - uint8_t rqdata[8]; + /* For ease of filling in from file data */ + union { + struct platform_event_msg emsg; + uint8_t bytes[sizeof(struct platform_event_msg)]; + } __attribute__ ((packed)) rqdata; char buf[1024]; char * ptr, * tok; - int i, j; - uint8_t chmed; int rc = 0; - if (file == NULL) + if (!file) return -1; - memset(rqdata, 0, 8); - - /* setup Platform Event Message command */ - memset(&req, 0, sizeof(req)); - req.msg.netfn = IPMI_NETFN_SE; - req.msg.cmd = 0x02; - req.msg.data = rqdata; - req.msg.data_len = 7; - - chmed = ipmi_current_channel_medium(intf); - if (chmed == IPMI_CHANNEL_MEDIUM_SYSTEM) { - /* system interface, need extra generator ID */ - rqdata[0] = 0x41; // As per Fig. 29-2 and Table 5-4 - req.msg.data_len = 8; - } - fp = ipmi_open_file_read(file); - if (fp == NULL) + if (!fp) return -1; while (feof(fp) == 0) { - if (fgets(buf, 1024, fp) == NULL) + size_t count = 0; + if (!fgets(buf, 1024, fp)) continue; + /* Each line is a new event */ + memset(&rqdata, 0, sizeof(rqdata)); + /* clip off optional comment tail indicated by # */ ptr = strchr(buf, '#'); if (ptr) @@ -541,49 +542,28 @@ ipmi_event_fromfile(struct ipmi_intf * intf, char * file) /* parse the event, 7 bytes with optional comment */ /* 0x00 0x00 0x00 0x00 0x00 0x00 0x00 # event */ - i = 0; tok = strtok(ptr, " "); while (tok) { - if (i == 7) + if (count == sizeof(struct platform_event_msg)) break; - j = i++; - if (chmed == IPMI_CHANNEL_MEDIUM_SYSTEM) - j++; - rqdata[j] = (uint8_t)strtol(tok, NULL, 0); + if (0 > str2uchar(tok, &rqdata.bytes[count])) { + lprintf(LOG_ERR, "Invalid token in file: [%s]", tok); + rc = -1; + break; + } tok = strtok(NULL, " "); + ++count; } - if (i < 7) { + if (count < sizeof(struct platform_event_msg)) { lprintf(LOG_ERR, "Invalid Event: %s", - buf2str(rqdata, sizeof(rqdata))); + buf2str(rqdata.bytes, sizeof(rqdata.bytes))); continue; } - memset(&sel_event, 0, sizeof(struct sel_event_record)); - sel_event.record_id = 0; - sel_event.sel_type.standard_type.gen_id = 2; - - j = (chmed == IPMI_CHANNEL_MEDIUM_SYSTEM) ? 1 : 0; - sel_event.sel_type.standard_type.evm_rev = rqdata[j++]; - sel_event.sel_type.standard_type.sensor_type = rqdata[j++]; - sel_event.sel_type.standard_type.sensor_num = rqdata[j++]; - sel_event.sel_type.standard_type.event_type = rqdata[j] & 0x7f; - sel_event.sel_type.standard_type.event_dir = (rqdata[j++] & 0x80) >> 7; - sel_event.sel_type.standard_type.event_data[0] = rqdata[j++]; - sel_event.sel_type.standard_type.event_data[1] = rqdata[j++]; - sel_event.sel_type.standard_type.event_data[2] = rqdata[j++]; - - ipmi_sel_print_std_entry(intf, &sel_event); - - rsp = intf->sendrecv(intf, &req); - if (rsp == NULL) { - lprintf(LOG_ERR, "Platform Event Message command failed"); - rc = -1; - } - else if (rsp->ccode > 0) { - lprintf(LOG_ERR, "Platform Event Message command failed: %s", - val2str(rsp->ccode, completion_code_vals)); - rc = -1; - } + /* Now actually send it, failures will be logged by the sender */ + rc = ipmi_send_platform_event(intf, &rqdata.emsg); + if (IPMI_CC_OK != rc) + break; } fclose(fp); @@ -616,11 +596,11 @@ ipmi_event_main(struct ipmi_intf * intf, int argc, char ** argv) { int rc = 0; - if (argc == 0 || strncmp(argv[0], "help", 4) == 0) { + if (argc == 0 || !strcmp(argv[0], "help")) { ipmi_event_usage(); return 0; } - if (strncmp(argv[0], "file", 4) == 0) { + if (!strcmp(argv[0], "file")) { if (argc < 2) { ipmi_event_usage(); return 0; |