From 155c34fbb61071f5b51240c4a50b49391e0877c1 Mon Sep 17 00:00:00 2001 From: Matthew Barth Date: Tue, 18 Oct 2016 14:33:17 -0500 Subject: Change H->hpp & C->cpp Change-Id: I4bb8cf7a58c517f348a524d3e027ebcd1dcd0dea Signed-off-by: Matthew Barth --- strgfnhandler.cpp | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 strgfnhandler.cpp (limited to 'strgfnhandler.cpp') diff --git a/strgfnhandler.cpp b/strgfnhandler.cpp new file mode 100644 index 0000000..66eda15 --- /dev/null +++ b/strgfnhandler.cpp @@ -0,0 +1,103 @@ +#include +#include +#include +#include +#include "writefrudata.hpp" + +void register_netfn_storage_write_fru() __attribute__((constructor)); + +sd_bus* ipmid_get_sd_bus_connection(void); + +///------------------------------------------------------- +// Called by IPMI netfn router for write fru data command +//-------------------------------------------------------- +ipmi_ret_t ipmi_storage_write_fru_data(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) +{ + FILE *fp = NULL; + char fru_file_name[16] = {0}; + uint8_t offset = 0; + uint16_t len = 0; + ipmi_ret_t rc = IPMI_CC_INVALID; + const char *mode = NULL; + + // From the payload, extract the header that has fruid and the offsets + write_fru_data_t *reqptr = (write_fru_data_t*)request; + + // Maintaining a temporary file to pump the data + sprintf(fru_file_name, "%s%02x", "/tmp/ipmifru", reqptr->frunum); + + offset = ((uint16_t)reqptr->offsetms) << 8 | reqptr->offsetls; + + // Length is the number of request bytes minus the header itself. + // The header contains an extra byte to indicate the start of + // the data (so didn't need to worry about word/byte boundaries) + // hence the -1... + len = ((uint16_t)*data_len) - (sizeof(write_fru_data_t)-1); + + // On error there is no response data for this command. + *data_len = 0; + +#ifdef __IPMI__DEBUG__ + printf("IPMI WRITE-FRU-DATA for [%s] Offset = [%d] Length = [%d]\n", + fru_file_name, offset, len); +#endif + + + if( access( fru_file_name, F_OK ) == -1 ) { + mode = "wb"; + } else { + mode = "rb+"; + } + + if ((fp = fopen(fru_file_name, mode)) != NULL) + { + if(fseek(fp, offset, SEEK_SET)) + { + perror("Error:"); + fclose(fp); + return rc; + } + + if(fwrite(&reqptr->data, len, 1, fp) != 1) + { + perror("Error:"); + fclose(fp); + return rc; + } + + fclose(fp); + } + else + { + fprintf(stderr, "Error trying to write to fru file %s\n",fru_file_name); + return rc; + } + + + // If we got here then set the resonse byte + // to the number of bytes written + memcpy(response, &len, 1); + *data_len = 1; + rc = IPMI_CC_OK; + + // Get the reference to global sd_bus object + sd_bus *bus_type = ipmid_get_sd_bus_connection(); + + // We received some bytes. It may be full or partial. Send a valid + // FRU file to the inventory controller on DBus for the correct number + bool bmc_fru = false; + ipmi_validate_fru_area(reqptr->frunum, fru_file_name, bus_type, bmc_fru); + + return rc; +} + +//------------------------------------------------------- +// Registering WRITE FRU DATA command handler with daemon +//------------------------------------------------------- +void register_netfn_storage_write_fru() +{ + printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_STORAGE, IPMI_CMD_WRITE_FRU_DATA); + ipmi_register_callback(NETFUN_STORAGE, IPMI_CMD_WRITE_FRU_DATA, NULL, ipmi_storage_write_fru_data); +} -- cgit v1.2.1