From 8a2a675ea683ac741f94e2a9b19ca5a3734164c2 Mon Sep 17 00:00:00 2001 From: Deepak Kodihalli Date: Sat, 11 Feb 2017 03:04:38 -0600 Subject: Fix bug in FRU data processing logic The logic assumed IPMI FRU data is encoded in ascii always, but the data could be ascii or binary. Handle both encodings. Change-Id: Ie89bb077fd32a23bb96bd4cda78b66d2ccdd9774 Signed-off-by: Deepak Kodihalli --- frup.cpp | 196 ++++++++++----------------------------------------------------- 1 file changed, 31 insertions(+), 165 deletions(-) (limited to 'frup.cpp') diff --git a/frup.cpp b/frup.cpp index 3cdf5b5..fdb34cf 100644 --- a/frup.cpp +++ b/frup.cpp @@ -714,11 +714,15 @@ ipmi_fru_product_info_area (const void *areabuf, return (rv); } -void _append_to_dict (uint8_t vpd_key_id, uint8_t* vpd_key_val, sd_bus_message* vpdtbl) +void _append_to_dict (uint8_t vpd_key_id, + uint8_t* vpd_key_val, + IPMIFruInfo& info) { int type_length = vpd_key_val[0]; - int type_code = (type_length & IPMI_FRU_TYPE_LENGTH_TYPE_CODE_MASK) >> IPMI_FRU_TYPE_LENGTH_TYPE_CODE_SHIFT; - int vpd_val_len = type_length & IPMI_FRU_TYPE_LENGTH_NUMBER_OF_DATA_BYTES_MASK; + int type_code = (type_length & IPMI_FRU_TYPE_LENGTH_TYPE_CODE_MASK) >> + IPMI_FRU_TYPE_LENGTH_TYPE_CODE_SHIFT; + int vpd_val_len = + type_length & IPMI_FRU_TYPE_LENGTH_NUMBER_OF_DATA_BYTES_MASK; int sdr=0; /* Needed to convert each uint8_t byte to a ascii */ @@ -759,14 +763,21 @@ void _append_to_dict (uint8_t vpd_key_id, uint8_t* vpd_key_val, sd_bus_message* strncpy(bin_in_ascii, "0x", 2); } - printf ("_append_to_dict: VPD Key = [%s] : Type Code = [BINARY] : Len = [%d] : Val = [%s]\n", + printf ("_append_to_dict: VPD Key = [%s] : Type Code = [BINARY] :" + " Len = [%d] : Val = [%s]\n", vpd_key_names [vpd_key_id], vpd_val_len, bin_in_ascii); - sdr = sd_bus_message_append (vpdtbl, "{sv}", vpd_key_names[vpd_key_id], "s", bin_in_ascii); + info[vpd_key_id] = std::make_pair(vpd_key_names[vpd_key_id], + bin_in_ascii); break; case 3: - printf ("_append_to_dict: VPD Key = [%s] : Type Code = [ASCII+Latin] : Len = [%d] : Val = [%s]\n", vpd_key_names [vpd_key_id], vpd_val_len, &vpd_key_val[1]); - sdr = sd_bus_message_append (vpdtbl, "{sv}", vpd_key_names[vpd_key_id], "s", &vpd_key_val[1]); + printf ("_append_to_dict: VPD Key = [%s] : Type Code=[ASCII+Latin]" + " : Len = [%d] : Val = [%s]\n", + vpd_key_names [vpd_key_id], vpd_val_len, &vpd_key_val[1]); + info[vpd_key_id] = std::make_pair( + vpd_key_names[vpd_key_id], + std::string(vpd_key_val + 1, + vpd_key_val + 1 + type_length)); break; } @@ -785,150 +796,6 @@ void _append_to_dict (uint8_t vpd_key_id, uint8_t* vpd_key_val, sd_bus_message* } } -int -parse_fru (const void* msgbuf, sd_bus_message* vpdtbl) -{ - int rv = -1; - int i = 0; - ipmi_fru_area_info_t fru_area_info [ IPMI_FRU_AREA_TYPE_MAX ]; - ipmi_fru_common_hdr_t* chdr = NULL; - uint8_t* hdr = NULL; - char timestr [ OPENBMC_VPD_VAL_LEN ]; - - - ipmi_fru_field_t vpd_info [ OPENBMC_VPD_KEY_MAX ]; - //uint8_t* ipmi_fru_field_str; - - /* Chassis */ - uint8_t chassis_type; - - /* Board */ - uint32_t mfg_date_time; - - /* Product */ - //unsigned int product_custom_fields_len; - - ASSERT (msgbuf); - ASSERT (vpdtbl); - - for (i=0; iinternal; - fru_area_info [ IPMI_FRU_AREA_CHASSIS_INFO ].off = chdr->chassis; - fru_area_info [ IPMI_FRU_AREA_BOARD_INFO ].off = chdr->board; - fru_area_info [ IPMI_FRU_AREA_PRODUCT_INFO ].off = chdr->product; - fru_area_info [ IPMI_FRU_AREA_MULTI_RECORD ].off = chdr->multirec; - - if (chdr->internal) - { - fru_area_info [ IPMI_FRU_AREA_INTERNAL_USE ].len = 8*(*(hdr+8*chdr->internal+1)); - - /* TODO: Parse internal use area */ - } - - if (chdr->chassis) - { - fru_area_info [ IPMI_FRU_AREA_CHASSIS_INFO ].len = 8*(*(hdr+8*chdr->chassis+1)); - ipmi_fru_chassis_info_area (hdr+8*chdr->chassis+2, - fru_area_info [ IPMI_FRU_AREA_CHASSIS_INFO ].len, - &chassis_type, - &vpd_info [OPENBMC_VPD_KEY_CHASSIS_PART_NUM], - &vpd_info [OPENBMC_VPD_KEY_CHASSIS_SERIAL_NUM], - &vpd_info [OPENBMC_VPD_KEY_CHASSIS_CUSTOM1], - OPENBMC_VPD_KEY_CUSTOM_FIELDS_MAX); - } - - if (chdr->board) - { - fru_area_info [ IPMI_FRU_AREA_BOARD_INFO ].len = 8*(*(hdr+8*chdr->board+1)); - ipmi_fru_board_info_area (hdr+8*chdr->board+2, - fru_area_info [ IPMI_FRU_AREA_BOARD_INFO ].len, - NULL, - &mfg_date_time, - &vpd_info [OPENBMC_VPD_KEY_BOARD_MFR], - &vpd_info [OPENBMC_VPD_KEY_BOARD_NAME], - &vpd_info [OPENBMC_VPD_KEY_BOARD_SERIAL_NUM], - &vpd_info [OPENBMC_VPD_KEY_BOARD_PART_NUM], - &vpd_info [OPENBMC_VPD_KEY_BOARD_FRU_FILE_ID], - &vpd_info [OPENBMC_VPD_KEY_BOARD_CUSTOM1], - OPENBMC_VPD_KEY_CUSTOM_FIELDS_MAX); - } - - if (chdr->product) - { - fru_area_info [ IPMI_FRU_AREA_PRODUCT_INFO ].len = 8*(*(hdr+8*chdr->product+1)); - ipmi_fru_product_info_area (hdr+8*chdr->product+2, - fru_area_info [ IPMI_FRU_AREA_PRODUCT_INFO ].len, - NULL, - &vpd_info [OPENBMC_VPD_KEY_PRODUCT_MFR], - &vpd_info [OPENBMC_VPD_KEY_PRODUCT_NAME], - &vpd_info [OPENBMC_VPD_KEY_PRODUCT_PART_MODEL_NUM], - &vpd_info [OPENBMC_VPD_KEY_PRODUCT_VER], - &vpd_info [OPENBMC_VPD_KEY_PRODUCT_SERIAL_NUM], - &vpd_info [OPENBMC_VPD_KEY_PRODUCT_ASSET_TAG], - &vpd_info [OPENBMC_VPD_KEY_PRODUCT_FRU_FILE_ID], - &vpd_info [OPENBMC_VPD_KEY_PRODUCT_CUSTOM1], - OPENBMC_VPD_KEY_CUSTOM_FIELDS_MAX); - } - - if (chdr->multirec) - { - fru_area_info [ IPMI_FRU_AREA_MULTI_RECORD ].len = 8*(*(hdr+8*chdr->multirec+1)); - /* TODO: Parse multi record area */ - } - - for (i=0; i - (vpd_info[i].type_length_field))); - } + //@TODO via https://github.com/openbmc/openbmc/issues/1091 - handle + //chassis FRU area. break; case IPMI_FRU_AREA_BOARD_INFO: #if IPMI_FRU_PARSER_DEBUG @@ -1013,15 +880,14 @@ int parse_fru_area (const uint8_t area, const void* msgbuf, { _to_time_str (mfg_date_time, timestr, OPENBMC_VPD_VAL_LEN); #if IPMI_FRU_PARSER_DEBUG - printf ("Board : Appending [%s] = [%d]\n", vpd_key_names[i], timestr); + printf ("Board : Appending [%s] = [%d]\n", + vpd_key_names[i], timestr); #endif info[i] = std::make_pair(vpd_key_names[i], std::string(timestr)); continue; } - info[i] = std::make_pair(vpd_key_names[i], - std::string(reinterpret_cast - (vpd_info[i].type_length_field))); + _append_to_dict (i, vpd_info[i].type_length_field, info); } break; @@ -1042,11 +908,11 @@ int parse_fru_area (const uint8_t area, const void* msgbuf, &vpd_info [OPENBMC_VPD_KEY_PRODUCT_CUSTOM1], OPENBMC_VPD_KEY_CUSTOM_FIELDS_MAX); - for (i=OPENBMC_VPD_KEY_PRODUCT_MFR; i<=OPENBMC_VPD_KEY_PRODUCT_MAX; i++) + for (i=OPENBMC_VPD_KEY_PRODUCT_MFR; + i<=OPENBMC_VPD_KEY_PRODUCT_MAX; + ++i) { - info[i] = std::make_pair(vpd_key_names[i], - std::string(reinterpret_cast - (vpd_info[i].type_length_field))); + _append_to_dict (i, vpd_info[i].type_length_field, info); } break; default: -- cgit v1.2.1