summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Amelkin <alexander@amelkin.msk.ru>2019-06-18 17:26:44 +0300
committerAlexander Amelkin <mocbuhtig@amelkin.msk.ru>2019-07-02 13:50:12 +0300
commit82d6629a665a0e8236c45e82c28ff3253f2ad251 (patch)
tree6579a8cfe44fc3631d3b48384712fa3a90dd72b4
parentc396a310ba5ca8487f32979a3397a155eefcdf12 (diff)
downloadipmitool-82d6629a665a0e8236c45e82c28ff3253f2ad251.tar.gz
event: Clean up the event sending code
Get rid of magic numbers, reduce code duplication Signed-off-by: Alexander Amelkin <alexander@amelkin.msk.ru>
-rw-r--r--include/ipmitool/ipmi_event.h27
-rw-r--r--lib/ipmi_event.c75
2 files changed, 65 insertions, 37 deletions
diff --git a/include/ipmitool/ipmi_event.h b/include/ipmitool/ipmi_event.h
index 2ba2fa5..3788533 100644
--- a/include/ipmitool/ipmi_event.h
+++ b/include/ipmitool/ipmi_event.h
@@ -61,6 +61,33 @@ struct platform_event_msg {
#pragma pack(0)
#endif
+/* See IPMI 2.0 Specification, Appendix G, Table G-1, "Event Commands" */
+typedef enum {
+ IPMI_CMD_SET_EVENT_RCVR = 0,
+ IPMI_CMD_GET_EVENT_RCVR,
+ IPMI_CMD_PLATFORM_EVENT
+} ipmi_event_cmd_t;
+
+typedef enum {
+ PLATFORM_EVENT_DATA_LEN_NON_SI = sizeof(struct platform_event_msg),
+ PLATFORM_EVENT_DATA_LEN_SI, /* System interfaces require generator ID */
+ PLATFORM_EVENT_DATA_LEN_MAX = PLATFORM_EVENT_DATA_LEN_SI
+} ipmi_platform_event_data_len_t;
+
+/* See Table 5-4 */
+typedef enum {
+ EVENT_SWID_BIOS_BASE = 0x00, /* BIOS */
+ EVENT_SWID_SMI_BASE = 0x10, /* SMI Handler */
+ EVENT_SWID_SMS_BASE = 0x20, /* System Management Software */
+ EVENT_SWID_OEM_BASE = 0x30, /* OEM */
+ EVENT_SWID_REMOTE_CONSOLE_BASE = 0x40, /* Remote Console SW */
+ EVENT_SWID_TERMINAL_MODE_BASE = 0x47 /* Terminal Mode RC SW */
+} ipmi_event_swid_t;
+#define EVENT_SWID(base, index) ((EVENT_SWID_##base##_BASE + index) & 0x7F)
+
+/* See Figure 29-2, Table 32-1 */
+#define EVENT_GENERATOR(base, index) (EVENT_SWID(base,index) << 1 | 1)
+
int ipmi_event_main(struct ipmi_intf *, int, char **);
#endif /*IPMI_EVENT_H*/
diff --git a/lib/ipmi_event.c b/lib/ipmi_event.c
index d9a5e4e..fca5b04 100644
--- a/lib/ipmi_event.c
+++ b/lib/ipmi_event.c
@@ -57,8 +57,8 @@ inline
bool
is_system(const struct channel_info_t *chinfo)
{
- return (IPMI_CHANNEL_MEDIUM_SYSTEM == chinfo.medium
- || CH_SYSTEM == chinfo.channel);
+ return (IPMI_CHANNEL_MEDIUM_SYSTEM == chinfo->medium
+ || CH_SYSTEM == chinfo->channel);
}
static void
@@ -91,15 +91,17 @@ 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 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;
ipmi_current_channel_info(intf, &chinfo);
if (chinfo.channel == CH_UNKNOWN) {
@@ -109,16 +111,14 @@ ipmi_send_platform_event(struct ipmi_intf * intf, struct platform_event_msg * em
}
if (is_system(&chinfo)) {
- /* 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));
- }
- else {
- req.msg.data_len = 7;
- memcpy(rqdata, emsg, sizeof(struct platform_event_msg));
+ /* 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);
@@ -501,24 +501,24 @@ ipmi_event_fromfile(struct ipmi_intf * intf, char * file)
struct ipmi_rs * rsp;
struct ipmi_rq req;
struct sel_event_record sel_event;
- uint8_t rqdata[8];
+ uint8_t rqdata[PLATFORM_EVENT_DATA_LEN_MAX];
+ uint8_t *rqdata_start = rqdata;
char buf[1024];
char * ptr, * tok;
- int i, j;
struct channel_info_t chinfo;
int rc = 0;
if (!file)
return -1;
- memset(rqdata, 0, 8);
+ memset(rqdata, 0, sizeof(rqdata));
/* setup Platform Event Message command */
memset(&req, 0, sizeof(req));
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 = 7;
+ req.msg.data_len = PLATFORM_EVENT_DATA_LEN_NON_SI;
ipmi_current_channel_info(intf, &chinfo);
if (chinfo.channel == CH_UNKNOWN) {
@@ -528,9 +528,10 @@ ipmi_event_fromfile(struct ipmi_intf * intf, char * file)
}
if (is_system(&chinfo)) {
- /* system interface, need extra generator ID */
- rqdata[0] = 0x41; // As per Fig. 29-2 and Table 5-4
- req.msg.data_len = 8;
+ /* system interface, need extra generator ID, see Fig. 29-2 */
+ rqdata[0] = EVENT_GENERATOR(REMOTE_CONSOLE, 1);
+ req.msg.data_len = PLATFORM_EVENT_DATA_LEN_SI;
+ rqdata_start++;
}
fp = ipmi_open_file_read(file);
@@ -538,6 +539,7 @@ ipmi_event_fromfile(struct ipmi_intf * intf, char * file)
return -1;
while (feof(fp) == 0) {
+ size_t count = 0;
if (!fgets(buf, 1024, fp))
continue;
@@ -560,19 +562,19 @@ 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;
+ if (0 > str2uchar(tok, &rqdata_start[count])) {
+ lprintf(LOG_ERR, "Invalid token in file: [%s]", tok);
+ rc = -1;
break;
- j = i++;
- if (is_system(&chinfo)) {
- j++;
}
- rqdata[j] = (uint8_t)strtol(tok, NULL, 0);
tok = strtok(NULL, " ");
+ ++count;
}
- if (i < 7) {
+ if (count < sizeof(struct platform_event_msg)) {
lprintf(LOG_ERR, "Invalid Event: %s",
buf2str(rqdata, sizeof(rqdata)));
continue;
@@ -582,15 +584,14 @@ ipmi_event_fromfile(struct ipmi_intf * intf, char * file)
sel_event.record_id = 0;
sel_event.sel_type.standard_type.gen_id = 2;
- j = (int)is_system(&chinfo);
- 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++];
+ /*
+ * Standard SEL record matches the platform event message
+ * format starting with the evm_rev field.
+ * Hence, just copy the message to the record at evm_rev.
+ */
+ memcpy(&sel_event.sel_type.standard_type.evm_rev,
+ rqdata_start,
+ sizeof(struct platform_event_msg));
ipmi_sel_print_std_entry(intf, &sel_event);