summaryrefslogtreecommitdiff
path: root/lib/ipmi_event.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ipmi_event.c')
-rw-r--r--lib/ipmi_event.c184
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;