event: Clean up the event sending code

Get rid of magic numbers, reduce code duplication

Signed-off-by: Alexander Amelkin <alexander@amelkin.msk.ru>
This commit is contained in:
Alexander Amelkin 2019-06-18 17:26:44 +03:00 committed by Alexander Amelkin
parent c396a310ba
commit 82d6629a66
2 changed files with 65 additions and 37 deletions

View File

@ -61,6 +61,33 @@ struct platform_event_msg {
#pragma pack(0) #pragma pack(0)
#endif #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 **); int ipmi_event_main(struct ipmi_intf *, int, char **);
#endif /*IPMI_EVENT_H*/ #endif /*IPMI_EVENT_H*/

View File

@ -57,8 +57,8 @@ inline
bool bool
is_system(const struct channel_info_t *chinfo) is_system(const struct channel_info_t *chinfo)
{ {
return (IPMI_CHANNEL_MEDIUM_SYSTEM == chinfo.medium return (IPMI_CHANNEL_MEDIUM_SYSTEM == chinfo->medium
|| CH_SYSTEM == chinfo.channel); || CH_SYSTEM == chinfo->channel);
} }
static void 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_rs * rsp;
struct ipmi_rq req; 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; struct channel_info_t chinfo;
memset(&req, 0, sizeof(req)); memset(&req, 0, sizeof(req));
memset(rqdata, 0, 8); memset(rqdata, 0, sizeof(rqdata));
req.msg.netfn = IPMI_NETFN_SE; req.msg.netfn = IPMI_NETFN_SE;
req.msg.cmd = 0x02; req.msg.cmd = IPMI_CMD_PLATFORM_EVENT;
req.msg.data = rqdata; req.msg.data = rqdata;
req.msg.data_len = PLATFORM_EVENT_DATA_LEN_NON_SI;
ipmi_current_channel_info(intf, &chinfo); ipmi_current_channel_info(intf, &chinfo);
if (chinfo.channel == CH_UNKNOWN) { 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)) { if (is_system(&chinfo)) {
/* system interface, need extra generator ID */ /* system interface, need extra generator ID, see Fig. 29-2 */
req.msg.data_len = 8; req.msg.data_len = PLATFORM_EVENT_DATA_LEN_SI;
rqdata[0] = 0x41; // As per Fig. 29-2 and Table 5-4 rqdata[0] = EVENT_GENERATOR(SMS, 0);
memcpy(rqdata+1, emsg, sizeof(struct platform_event_msg)); rqdata_start++;
}
else {
req.msg.data_len = 7;
memcpy(rqdata, emsg, sizeof(struct platform_event_msg));
} }
memcpy(rqdata_start, emsg, sizeof(struct platform_event_msg));
ipmi_event_msg_print(intf, emsg); ipmi_event_msg_print(intf, emsg);
rsp = intf->sendrecv(intf, &req); rsp = intf->sendrecv(intf, &req);
@ -501,24 +501,24 @@ ipmi_event_fromfile(struct ipmi_intf * intf, char * file)
struct ipmi_rs * rsp; struct ipmi_rs * rsp;
struct ipmi_rq req; struct ipmi_rq req;
struct sel_event_record sel_event; 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 buf[1024];
char * ptr, * tok; char * ptr, * tok;
int i, j;
struct channel_info_t chinfo; struct channel_info_t chinfo;
int rc = 0; int rc = 0;
if (!file) if (!file)
return -1; return -1;
memset(rqdata, 0, 8); memset(rqdata, 0, sizeof(rqdata));
/* setup Platform Event Message command */ /* setup Platform Event Message command */
memset(&req, 0, sizeof(req)); memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_SE; req.msg.netfn = IPMI_NETFN_SE;
req.msg.cmd = 0x02; req.msg.cmd = IPMI_CMD_PLATFORM_EVENT;
req.msg.data = rqdata; 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); ipmi_current_channel_info(intf, &chinfo);
if (chinfo.channel == CH_UNKNOWN) { if (chinfo.channel == CH_UNKNOWN) {
@ -528,9 +528,10 @@ ipmi_event_fromfile(struct ipmi_intf * intf, char * file)
} }
if (is_system(&chinfo)) { if (is_system(&chinfo)) {
/* system interface, need extra generator ID */ /* system interface, need extra generator ID, see Fig. 29-2 */
rqdata[0] = 0x41; // As per Fig. 29-2 and Table 5-4 rqdata[0] = EVENT_GENERATOR(REMOTE_CONSOLE, 1);
req.msg.data_len = 8; req.msg.data_len = PLATFORM_EVENT_DATA_LEN_SI;
rqdata_start++;
} }
fp = ipmi_open_file_read(file); fp = ipmi_open_file_read(file);
@ -538,6 +539,7 @@ ipmi_event_fromfile(struct ipmi_intf * intf, char * file)
return -1; return -1;
while (feof(fp) == 0) { while (feof(fp) == 0) {
size_t count = 0;
if (!fgets(buf, 1024, fp)) if (!fgets(buf, 1024, fp))
continue; continue;
@ -560,19 +562,19 @@ ipmi_event_fromfile(struct ipmi_intf * intf, char * file)
/* parse the event, 7 bytes with optional comment */ /* parse the event, 7 bytes with optional comment */
/* 0x00 0x00 0x00 0x00 0x00 0x00 0x00 # event */ /* 0x00 0x00 0x00 0x00 0x00 0x00 0x00 # event */
i = 0;
tok = strtok(ptr, " "); tok = strtok(ptr, " ");
while (tok) { 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; break;
j = i++;
if (is_system(&chinfo)) {
j++;
} }
rqdata[j] = (uint8_t)strtol(tok, NULL, 0);
tok = strtok(NULL, " "); tok = strtok(NULL, " ");
++count;
} }
if (i < 7) { if (count < sizeof(struct platform_event_msg)) {
lprintf(LOG_ERR, "Invalid Event: %s", lprintf(LOG_ERR, "Invalid Event: %s",
buf2str(rqdata, sizeof(rqdata))); buf2str(rqdata, sizeof(rqdata)));
continue; continue;
@ -582,15 +584,14 @@ ipmi_event_fromfile(struct ipmi_intf * intf, char * file)
sel_event.record_id = 0; sel_event.record_id = 0;
sel_event.sel_type.standard_type.gen_id = 2; sel_event.sel_type.standard_type.gen_id = 2;
j = (int)is_system(&chinfo); /*
sel_event.sel_type.standard_type.evm_rev = rqdata[j++]; * Standard SEL record matches the platform event message
sel_event.sel_type.standard_type.sensor_type = rqdata[j++]; * format starting with the evm_rev field.
sel_event.sel_type.standard_type.sensor_num = rqdata[j++]; * Hence, just copy the message to the record at evm_rev.
sel_event.sel_type.standard_type.event_type = rqdata[j] & 0x7f; */
sel_event.sel_type.standard_type.event_dir = (rqdata[j++] & 0x80) >> 7; memcpy(&sel_event.sel_type.standard_type.evm_rev,
sel_event.sel_type.standard_type.event_data[0] = rqdata[j++]; rqdata_start,
sel_event.sel_type.standard_type.event_data[1] = rqdata[j++]; sizeof(struct platform_event_msg));
sel_event.sel_type.standard_type.event_data[2] = rqdata[j++];
ipmi_sel_print_std_entry(intf, &sel_event); ipmi_sel_print_std_entry(intf, &sel_event);