#include "systemintfcmds.h" #include "host-ipmid/ipmid-api.h" #include void register_netfn_app_functions() __attribute__((constructor)); //------------------------------------------------------------------- // Called by Host post response from Get_Message_Flags //------------------------------------------------------------------- ipmi_ret_t ipmi_app_read_event(ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request, ipmi_response_t response, ipmi_data_len_t data_len, ipmi_context_t context) { ipmi_ret_t rc = IPMI_CC_OK; printf("IPMI APP READ EVENT command received\n"); // TODO : For now, this is catering only to the Soft Power Off via OEM SEL // mechanism. If we need to make this generically used for some // other conditions, then we can take advantage of context pointer. struct oem_sel_timestamped soft_off = {0}; *data_len = sizeof(struct oem_sel_timestamped); // either id[0] -or- id[1] can be filled in. We will use id[0] soft_off.id[0] = SEL_OEM_ID_0; soft_off.id[1] = SEL_OEM_ID_0; soft_off.type = SEL_RECORD_TYPE_OEM; // Following 3 bytes are from IANA Manufactre_Id field. See below soft_off.manuf_id[0]= 0x41; soft_off.manuf_id[1]= 0xA7; soft_off.manuf_id[2]= 0x00; // per IPMI spec NetFuntion for OEM soft_off.netfun = 0x3A; // Mechanism to kick start soft shutdown. soft_off.cmd = CMD_POWER; soft_off.data[0] = SOFT_OFF; // All '0xFF' since unused. memset(&soft_off.data[1], 0xFF, 3); // Pack the actual response memcpy(response, &soft_off, *data_len); return rc; } //--------------------------------------------------------------------- // Called by Host on seeing a SMS_ATN bit set. Return a hardcoded // value of 0x2 indicating we need Host read some data. //------------------------------------------------------------------- ipmi_ret_t ipmi_app_get_msg_flags(ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request, ipmi_response_t response, ipmi_data_len_t data_len, ipmi_context_t context) { // Generic return from IPMI commands. ipmi_ret_t rc = IPMI_CC_OK; printf("IPMI APP GET MSG FLAGS returning with [bit:2] set\n"); // From IPMI spec V2.0 for Get Message Flags Command : // bit:[1] from LSB : 1b = Event Message Buffer Full. // Return as 0 if Event Message Buffer is not supported, // or when the Event Message buffer is disabled. // TODO. For now. assume its not disabled and send "0x2" anyway: uint8_t set_event_msg_buffer_full = 0x2; *data_len = sizeof(set_event_msg_buffer_full); // Pack the actual response memcpy(response, &set_event_msg_buffer_full, *data_len); return rc; } ipmi_ret_t ipmi_app_set_bmc_global_enables(ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request, ipmi_response_t response, ipmi_data_len_t data_len, ipmi_context_t context) { ipmi_ret_t rc = IPMI_CC_OK; *data_len = 0; // Event and message logging enabled by default so return for now printf("IPMI APP SET BMC GLOBAL ENABLES Ignoring for now\n"); return rc; } void register_netfn_app_functions() { // printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_READ_EVENT); ipmi_register_callback(NETFUN_APP, IPMI_CMD_READ_EVENT, NULL, ipmi_app_read_event, SYSTEM_INTERFACE); // printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_SET_BMC_GLOBAL_ENABLES); ipmi_register_callback(NETFUN_APP, IPMI_CMD_SET_BMC_GLOBAL_ENABLES, NULL, ipmi_app_set_bmc_global_enables, SYSTEM_INTERFACE); // printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_GET_MSG_FLAGS); ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_MSG_FLAGS, NULL, ipmi_app_get_msg_flags, SYSTEM_INTERFACE); return; }