summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvishwa <vishwanath@in.ibm.com>2016-06-10 06:08:56 -0500
committervishwa <vishwanath@in.ibm.com>2016-06-15 05:15:51 -0500
commit24afbb9cab4f9de8501120b179f9bfe8b304d624 (patch)
treef60bb6e963dedd411722af2266465fdd7598981f
parentbf9385f56f715426ff2ac3a1d77af6b6d1575fe1 (diff)
downloadipmi-fru-parser-24afbb9cab4f9de8501120b179f9bfe8b304d624.tar.gz
ipmi-fru-parser-24afbb9cab4f9de8501120b179f9bfe8b304d624.zip
Update BINARY encoded IPMI FRU area data to FRU Inventory
IPMI fru record format can contain BINARY and ASCII encodings. There was an error in the way FRU parser was handling the BINARY encoded data and that resulted in incorrect updates to FRU Inventory object. The reason why it was done like that was to workaround a limitation encountered while creating the dictionary having a name and value pair where value is an array of bytes. This proposed fix will convert the array of binary encoded data into ascii string and updates the FRU inventory as a string. Since string is a single element, it fits in within the limits of dictionary. Fixes openbmc/ipmi-fru-parser#3
-rw-r--r--frup.c51
1 files changed, 46 insertions, 5 deletions
diff --git a/frup.c b/frup.c
index 49718ba..4d3758a 100644
--- a/frup.c
+++ b/frup.c
@@ -770,7 +770,6 @@ ipmi_fru_product_info_area (const void *areabuf,
return (rv);
}
-
int _append_to_dict (uint8_t vpd_key_id, uint8_t* vpd_key_val, sd_bus_message* vpdtbl)
{
int type_length = vpd_key_val[0];
@@ -778,19 +777,62 @@ int _append_to_dict (uint8_t vpd_key_id, uint8_t* vpd_key_val, sd_bus_message* v
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 */
+ char bin_byte[3] = {0};
+
+ /*
+ * Max number of characters needed to represent 1 unsigned byte in string
+ * is number of bytes multipled by 2. Extra 3 for 0x and a ending '\0';
+ */
+ char bin_in_ascii_len = vpd_val_len * 2 + 3;
+
+ /* Binary converted to ascii in array */
+ char *bin_in_ascii = (char *)malloc(bin_in_ascii_len);
+
+ /* For reading byte from the area */
+ size_t val = 0;
+
+ char *bin_copy = &((char *)bin_in_ascii)[2];
+
switch (type_code)
{
case 0:
- printf ("_append_to_dict: VPD Key = [%s] : Type Code = [BINARY] : 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], "ay", 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]);*/
+ memset(bin_in_ascii, 0x0, bin_in_ascii_len);
+
+ /* Offset 1 is where actual data starts */
+ for(val = 1; val <= vpd_val_len ; val++)
+ {
+ /* 2 bytes for data and 1 for terminating '\0' */
+ snprintf(bin_byte, 3, "%02x", vpd_key_val[val]);
+
+ /* Its a running string so strip off the '\0' */
+ strncat(bin_copy, bin_byte, 2);
+ }
+
+ /* We need the data represented as 0x...... */
+ if(vpd_val_len > 0)
+ {
+ strncpy(bin_in_ascii, "0x", 2);
+ }
+
+ 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);
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]);
break;
}
+ if(bin_in_ascii)
+ {
+ free(bin_in_ascii);
+ bin_in_ascii = NULL;
+ }
+
+
if (sdr < 0)
{
#if IPMI_FRU_PARSER_DEBUG
@@ -944,7 +986,6 @@ parse_fru (const void* msgbuf, sd_bus_message* vpdtbl)
}
out:
rv = 0;
- cleanup:
return (rv);
}
OpenPOWER on IntegriCloud