diff --git a/include/ipmitool/ipmi_channel.h b/include/ipmitool/ipmi_channel.h index 7ff723c..85d158f 100644 --- a/include/ipmitool/ipmi_channel.h +++ b/include/ipmitool/ipmi_channel.h @@ -57,6 +57,28 @@ #define IPMI_CHANNEL_SESSION_MULTI 0x80 #define IPMI_CHANNEL_SESSION_BASED 0xC0 +/* Fixed channel numbers as per Table 6-1 */ +typedef enum { + CH_PRIMARY_IPMB, + CH_IMP_SPECIFIC_1, + CH_IMP_SPECIFIC_2, + CH_IMP_SPECIFIC_3, + CH_IMP_SPECIFIC_4, + CH_IMP_SPECIFIC_5, + CH_IMP_SPECIFIC_6, + CH_IMP_SPECIFIC_7, + CH_IMP_SPECIFIC_8, + CH_IMP_SPECIFIC_9, + CH_IMP_SPECIFIC_A, + CH_IMP_SPECIFIC_B, + CH_RSVD1, + CH_RSVD2, + CH_CURRENT, + CH_SYSTEM, + CH_TOTAL, + CH_UNKNOWN = UINT8_MAX +} ipmi_channel_num_t; + /* (22.24) Get Channel Info */ struct channel_info_t { uint8_t channel; @@ -189,7 +211,8 @@ int _ipmi_set_channel_access(struct ipmi_intf *intf, uint8_t privilege_option); uint8_t ipmi_get_channel_medium(struct ipmi_intf * intf, uint8_t channel); -uint8_t ipmi_current_channel_medium(struct ipmi_intf * intf); +void ipmi_current_channel_info(struct ipmi_intf *intf, + struct channel_info_t *chinfo); int ipmi_channel_main(struct ipmi_intf * intf, int argc, char ** argv); int ipmi_get_channel_auth_cap(struct ipmi_intf * intf, uint8_t channel, uint8_t priv); diff --git a/lib/ipmi_channel.c b/lib/ipmi_channel.c index 65da32a..a6a6a42 100644 --- a/lib/ipmi_channel.c +++ b/lib/ipmi_channel.c @@ -244,10 +244,28 @@ ipmi_1_5_authtypes(uint8_t n) return supportedTypes; } -uint8_t -ipmi_current_channel_medium(struct ipmi_intf *intf) +void +ipmi_current_channel_info(struct ipmi_intf *intf, + struct channel_info_t *chinfo) { - return ipmi_get_channel_medium(intf, 0xE); + int ccode = 0; + + chinfo->channel = CH_CURRENT; + ccode = _ipmi_get_channel_info(intf, chinfo); + if (ccode) { + if (ccode != IPMI_CC_INV_DATA_FIELD_IN_REQ) { + if (ccode > 0) { + lprintf(LOG_ERR, "Get Channel Info command failed: %s", + val2str(ccode, completion_code_vals)); + } + else { + eval_ccode(ccode); + } + } + chinfo->channel = CH_UNKNOWN; + chinfo->medium = IPMI_CHANNEL_MEDIUM_RESERVED; + } + return; } /** @@ -684,13 +702,16 @@ ipmi_get_channel_medium(struct ipmi_intf *intf, uint8_t channel) channel_info.channel = channel; ccode = _ipmi_get_channel_info(intf, &channel_info); - if (ccode == 0xCC) { - return IPMI_CHANNEL_MEDIUM_RESERVED; - } else if (ccode < 0 && eval_ccode(ccode) != 0) { - return 0; - } else if (ccode) { - lprintf(LOG_ERR, "Get Channel Info command failed: %s", - val2str(ccode, completion_code_vals)); + if (ccode) { + if (ccode != IPMI_CC_INV_DATA_FIELD_IN_REQ) { + if (ccode > 0) { + lprintf(LOG_ERR, "Get Channel Info command failed: %s", + val2str(ccode, completion_code_vals)); + } + else { + eval_ccode(ccode); + } + } return IPMI_CHANNEL_MEDIUM_RESERVED; } lprintf(LOG_DEBUG, "Channel type: %s", diff --git a/lib/ipmi_event.c b/lib/ipmi_event.c index 0088032..d9a5e4e 100644 --- a/lib/ipmi_event.c +++ b/lib/ipmi_event.c @@ -52,6 +52,14 @@ #include #include +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) @@ -84,7 +92,7 @@ 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; + struct channel_info_t chinfo; memset(&req, 0, sizeof(req)); memset(rqdata, 0, 8); @@ -93,8 +101,14 @@ ipmi_send_platform_event(struct ipmi_intf * intf, struct platform_event_msg * em req.msg.cmd = 0x02; req.msg.data = rqdata; - chmed = ipmi_current_channel_medium(intf); - if (chmed == IPMI_CHANNEL_MEDIUM_SYSTEM) { + 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; + } + + 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 @@ -491,7 +505,7 @@ ipmi_event_fromfile(struct ipmi_intf * intf, char * file) char buf[1024]; char * ptr, * tok; int i, j; - uint8_t chmed; + struct channel_info_t chinfo; int rc = 0; if (!file) @@ -506,8 +520,14 @@ ipmi_event_fromfile(struct ipmi_intf * intf, char * file) req.msg.data = rqdata; req.msg.data_len = 7; - chmed = ipmi_current_channel_medium(intf); - if (chmed == IPMI_CHANNEL_MEDIUM_SYSTEM) { + ipmi_current_channel_info(intf, &chinfo); + if (chinfo.channel == CH_UNKNOWN) { + lprintf(LOG_ERR, "Failed to send the event from file " + "via an unknown channel"); + return -3; + } + + 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; @@ -546,8 +566,9 @@ ipmi_event_fromfile(struct ipmi_intf * intf, char * file) if (i == 7) break; j = i++; - if (chmed == IPMI_CHANNEL_MEDIUM_SYSTEM) + if (is_system(&chinfo)) { j++; + } rqdata[j] = (uint8_t)strtol(tok, NULL, 0); tok = strtok(NULL, " "); } @@ -561,7 +582,7 @@ ipmi_event_fromfile(struct ipmi_intf * intf, char * file) sel_event.record_id = 0; sel_event.sel_type.standard_type.gen_id = 2; - j = (chmed == IPMI_CHANNEL_MEDIUM_SYSTEM) ? 1 : 0; + 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++];