summaryrefslogtreecommitdiffstats
path: root/frup.cpp
diff options
context:
space:
mode:
authorDeepak Kodihalli <dkodihal@in.ibm.com>2017-02-11 03:04:38 -0600
committerDeepak Kodihalli <dkodihal@in.ibm.com>2017-02-14 13:00:19 -0600
commit8a2a675ea683ac741f94e2a9b19ca5a3734164c2 (patch)
tree44292aec7a3743003be4a7a8074771249045fdc6 /frup.cpp
parent89ededd0383bd60f5aadf3e73af489e79f138293 (diff)
downloadipmi-fru-parser-8a2a675ea683ac741f94e2a9b19ca5a3734164c2.tar.gz
ipmi-fru-parser-8a2a675ea683ac741f94e2a9b19ca5a3734164c2.zip
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 <dkodihal@in.ibm.com>
Diffstat (limited to 'frup.cpp')
-rw-r--r--frup.cpp196
1 files changed, 31 insertions, 165 deletions
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; i<OPENBMC_VPD_KEY_MAX; i++)
- {
- memset (vpd_info[i].type_length_field, '\0', IPMI_FRU_AREA_TYPE_LENGTH_FIELD_MAX);
- vpd_info[i].type_length_field_length = 0;
- }
-
- for (i=0; i<IPMI_FRU_AREA_TYPE_MAX; i++)
- {
- fru_area_info [ i ].off = 0;
- fru_area_info [ i ].len = 0;
- }
-
- chdr = (ipmi_fru_common_hdr_t*) msgbuf;
- hdr = (uint8_t*) msgbuf;
-
- fru_area_info [ IPMI_FRU_AREA_INTERNAL_USE ].off = chdr->internal;
- 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<IPMI_FRU_AREA_TYPE_MAX; i++)
- {
-#if IPMI_FRU_PARSER_DEBUG
- printf ("IPMI_FRU_AREA_TYPE=[%d] : Offset=[%d] : Len=[%d]\n", i, fru_area_info [i].off, fru_area_info[i].len);
-#endif
- }
-
- /* Populate VPD Table */
- for (i=1; i<OPENBMC_VPD_KEY_MAX; i++)
- {
- if (i==OPENBMC_VPD_KEY_CHASSIS_TYPE)
- {
- sd_bus_message_append (vpdtbl, "{sv}", vpd_key_names[i], "y", chassis_type);
-#if IPMI_FRU_PARSER_DEBUG
- printf ("[%s] = [%d]\n", vpd_key_names[i], chassis_type);
-#endif
- continue;
- }
-
- if (i==OPENBMC_VPD_KEY_BOARD_MFG_DATE)
- {
- _to_time_str (mfg_date_time, timestr, OPENBMC_VPD_VAL_LEN);
- sd_bus_message_append (vpdtbl, "{sv}", vpd_key_names[i], "s", timestr);
-#if IPMI_FRU_PARSER_DEBUG
- printf ("[%s] = [%d]\n", vpd_key_names[i], mfg_date_time);
-#endif
- continue;
- }
-
- /* Append TypeLen Field to Dictionary */
- _append_to_dict (i, vpd_info[i].type_length_field, vpdtbl);
-
- /*ipmi_fru_field_str = (unsigned char*) &(vpd_info[i].type_length_field) + 1;*/
- /*sd_bus_message_append (vpdtbl, "{sv}", vpd_key_names[i], "s", ipmi_fru_field_str); */
- }
- rv = 0;
- return (rv);
-}
-
int parse_fru_area (const uint8_t area, const void* msgbuf,
const size_t len, IPMIFruInfo& info)
{
@@ -954,7 +821,8 @@ int parse_fru_area (const uint8_t area, const void* msgbuf,
for (i=0; i<OPENBMC_VPD_KEY_MAX; i++)
{
- memset (vpd_info[i].type_length_field, '\0', IPMI_FRU_AREA_TYPE_LENGTH_FIELD_MAX);
+ memset (vpd_info[i].type_length_field, '\0',
+ IPMI_FRU_AREA_TYPE_LENGTH_FIELD_MAX);
vpd_info[i].type_length_field_length = 0;
}
@@ -978,17 +846,16 @@ int parse_fru_area (const uint8_t area, const void* msgbuf,
if (i==OPENBMC_VPD_KEY_CHASSIS_TYPE)
{
#if IPMI_FRU_PARSER_DEBUG
- printf ("Chassis : Appending [%s] = [%d]\n", vpd_key_names[i], chassis_type);
+ printf ("Chassis : Appending [%s] = [%d]\n",
+ vpd_key_names[i], chassis_type);
#endif
info[i] = std::make_pair(vpd_key_names[i],
std::to_string(chassis_type));
continue;
}
- info[i] = std::make_pair(vpd_key_names[i],
- std::string(reinterpret_cast<char*>
- (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<char*>
- (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<char*>
- (vpd_info[i].type_length_field)));
+ _append_to_dict (i, vpd_info[i].type_length_field, info);
}
break;
default:
OpenPOWER on IntegriCloud