in common/recipes-lib/fruid/files/fruid.c [1255:1949]
int fruid_modify(const char * cur_bin, const char * new_bin, const char * field, const char * content)
{
int fruid_len, ret;
FILE *fruid_fd;
uint8_t *old_eeprom, *eeprom = NULL;
int total_field_opt_size = sizeof(fruid_field_all_opt)/sizeof(fruid_field_all_opt[0]);
fruid_info_t fruid;
int i, len;
int target = -1;
char *tmp_content = NULL;
int content_len;
int new_fruid_len;
uint8_t type_length;
/* Reset parser return value */
ret = 0;
/* Open the FRUID binary file */
fruid_fd = fopen(cur_bin, "rb");
if (!fruid_fd) {
#ifdef DEBUG
syslog(LOG_ERR, "fruid: unable to open the file");
#endif
return ENOENT;
}
/* Get the size of the binary file */
fseek(fruid_fd, 0, SEEK_END);
fruid_len = (uint32_t) ftell(fruid_fd);
fseek(fruid_fd, 0, SEEK_SET);
old_eeprom = (uint8_t *) malloc(fruid_len);
if (!old_eeprom) {
#ifdef DEBUG
syslog(LOG_WARNING, "fruid: malloc: memory allocation failed\n");
#endif
return ENOMEM;
}
/* Read the binary file */
ret = fread(old_eeprom, sizeof(uint8_t), fruid_len, fruid_fd);
if (ret != fruid_len) {
printf("Failed to read binary file, inconsistent length\n");
return -1;
}
/* Close the FRUID binary file */
fclose(fruid_fd);
/* Parse eeprom dump*/
ret = fruid_parse_eeprom(old_eeprom, fruid_len, &fruid);
/* Free the eeprom malloced memory */
free(old_eeprom);
if (ret) {
printf("Failed to parse FRU!\n");
return -1;
}
for(i = 0; i < total_field_opt_size; i++) {
if (!strcmp(field, fruid_field_all_opt[i])) {
target = i;
break;
}
}
if (target == -1) {
printf("Parameter \"%s\" is invalid!\n", field);
return -1;
}
if (target <= CCD6) {
if (fruid.chassis.flag != 1) {
printf("Chassis Area is invalid!\n");
return -1;
}
} else if (target <= BCD6) {
if (fruid.board.flag != 1) {
printf("Board Area is invalid!\n");
return -1;
}
} else {
if (fruid.product.flag != 1) {
printf("Product Area is invalid!\n");
return -1;
}
}
tmp_content = extract_content(content);
content_len = strlen(tmp_content);
if (content_len > MAX_FIELD_LENGTH) {
printf("Content length \"%s\" is more than its maximum length:%d !\n", field, MAX_FIELD_LENGTH);
return -1;
}
if (content_len)
type_length = 0xc0 + content_len;
else
type_length = 0;
// check custom field type length
switch (target) {
case CCD1:
case CCD2:
case CCD3:
case CCD4:
case CCD5:
case CCD6:
case BCD1:
case BCD2:
case BCD3:
case BCD4:
case BCD5:
case BCD6:
case PCD1:
case PCD2:
case PCD3:
case PCD4:
case PCD5:
case PCD6:
if (type_length == NO_MORE_DATA_BYTE) {
printf("Content length \"%s\" should not be 1 !\n", field);
return -1;
}
break;
default:
break;
}
// alter field content
switch (target) {
case CPN:
fruid.chassis.part_type_len = type_length;
alter_field_content(&fruid.chassis.part,tmp_content);
break;
case CSN:
fruid.chassis.serial_type_len = type_length;
alter_field_content(&fruid.chassis.serial,tmp_content);
break;
case CCD1:
fruid.chassis.custom1_type_len = type_length;
alter_field_content(&fruid.chassis.custom1,tmp_content);
break;
case CCD2:
if (fruid.chassis.custom1_type_len == NO_MORE_DATA_BYTE)
fruid.chassis.custom1_type_len = 0;
fruid.chassis.custom2_type_len = type_length;
alter_field_content(&fruid.chassis.custom2,tmp_content);
break;
case CCD3:
if (fruid.chassis.custom1_type_len == NO_MORE_DATA_BYTE)
fruid.chassis.custom1_type_len = 0;
if (fruid.chassis.custom2_type_len == NO_MORE_DATA_BYTE)
fruid.chassis.custom2_type_len = 0;
fruid.chassis.custom3_type_len = type_length;
alter_field_content(&fruid.chassis.custom3,tmp_content);
break;
case CCD4:
if (fruid.chassis.custom1_type_len == NO_MORE_DATA_BYTE)
fruid.chassis.custom1_type_len = 0;
if (fruid.chassis.custom2_type_len == NO_MORE_DATA_BYTE)
fruid.chassis.custom2_type_len = 0;
if (fruid.chassis.custom3_type_len == NO_MORE_DATA_BYTE)
fruid.chassis.custom3_type_len = 0;
fruid.chassis.custom4_type_len = type_length;
alter_field_content(&fruid.chassis.custom4,tmp_content);
break;
case CCD5:
if (fruid.chassis.custom1_type_len == NO_MORE_DATA_BYTE)
fruid.chassis.custom1_type_len = 0;
if (fruid.chassis.custom2_type_len == NO_MORE_DATA_BYTE)
fruid.chassis.custom2_type_len = 0;
if (fruid.chassis.custom3_type_len == NO_MORE_DATA_BYTE)
fruid.chassis.custom3_type_len = 0;
if (fruid.chassis.custom4_type_len == NO_MORE_DATA_BYTE)
fruid.chassis.custom4_type_len = 0;
fruid.chassis.custom5_type_len = type_length;
alter_field_content(&fruid.chassis.custom5,tmp_content);
break;
case CCD6:
if (fruid.chassis.custom1_type_len == NO_MORE_DATA_BYTE)
fruid.chassis.custom1_type_len = 0;
if (fruid.chassis.custom2_type_len == NO_MORE_DATA_BYTE)
fruid.chassis.custom2_type_len = 0;
if (fruid.chassis.custom3_type_len == NO_MORE_DATA_BYTE)
fruid.chassis.custom3_type_len = 0;
if (fruid.chassis.custom4_type_len == NO_MORE_DATA_BYTE)
fruid.chassis.custom4_type_len = 0;
if (fruid.chassis.custom5_type_len == NO_MORE_DATA_BYTE)
fruid.chassis.custom5_type_len = 0;
fruid.chassis.custom6_type_len = type_length;
alter_field_content(&fruid.chassis.custom6,tmp_content);
break;
case BMD:
if(set_mfg_time(fruid.board.mfg_time, tmp_content) < 0) {
return -1;
}
break;
case BM:
fruid.board.mfg_type_len = type_length;
alter_field_content(&fruid.board.mfg,tmp_content);
break;
case BP:
fruid.board.name_type_len = type_length;
alter_field_content(&fruid.board.name,tmp_content);
break;
case BSN:
fruid.board.serial_type_len = type_length;
alter_field_content(&fruid.board.serial,tmp_content);
break;
case BPN:
fruid.board.part_type_len = type_length;
alter_field_content(&fruid.board.part,tmp_content);
break;
case BFI:
fruid.board.fruid_type_len = type_length;
alter_field_content(&fruid.board.fruid,tmp_content);
break;
case BCD1:
fruid.board.custom1_type_len = type_length;
alter_field_content(&fruid.board.custom1,tmp_content);
break;
case BCD2:
if (fruid.board.custom1_type_len == NO_MORE_DATA_BYTE)
fruid.board.custom1_type_len = 0;
fruid.board.custom2_type_len = type_length;
alter_field_content(&fruid.board.custom2,tmp_content);
break;
case BCD3:
if (fruid.board.custom1_type_len == NO_MORE_DATA_BYTE)
fruid.board.custom1_type_len = 0;
if (fruid.board.custom2_type_len == NO_MORE_DATA_BYTE)
fruid.board.custom2_type_len = 0;
fruid.board.custom3_type_len = type_length;
alter_field_content(&fruid.board.custom3,tmp_content);
break;
case BCD4:
if (fruid.board.custom1_type_len == NO_MORE_DATA_BYTE)
fruid.board.custom1_type_len = 0;
if (fruid.board.custom2_type_len == NO_MORE_DATA_BYTE)
fruid.board.custom2_type_len = 0;
if (fruid.board.custom3_type_len == NO_MORE_DATA_BYTE)
fruid.board.custom3_type_len = 0;
fruid.board.custom4_type_len = type_length;
alter_field_content(&fruid.board.custom4,tmp_content);
break;
case BCD5:
if (fruid.board.custom1_type_len == NO_MORE_DATA_BYTE)
fruid.board.custom1_type_len = 0;
if (fruid.board.custom2_type_len == NO_MORE_DATA_BYTE)
fruid.board.custom2_type_len = 0;
if (fruid.board.custom3_type_len == NO_MORE_DATA_BYTE)
fruid.board.custom3_type_len = 0;
if (fruid.board.custom4_type_len == NO_MORE_DATA_BYTE)
fruid.board.custom4_type_len = 0;
fruid.board.custom5_type_len = type_length;
alter_field_content(&fruid.board.custom5,tmp_content);
break;
case BCD6:
if (fruid.board.custom1_type_len == NO_MORE_DATA_BYTE)
fruid.board.custom1_type_len = 0;
if (fruid.board.custom2_type_len == NO_MORE_DATA_BYTE)
fruid.board.custom2_type_len = 0;
if (fruid.board.custom3_type_len == NO_MORE_DATA_BYTE)
fruid.board.custom3_type_len = 0;
if (fruid.board.custom4_type_len == NO_MORE_DATA_BYTE)
fruid.board.custom4_type_len = 0;
if (fruid.board.custom5_type_len == NO_MORE_DATA_BYTE)
fruid.board.custom5_type_len = 0;
fruid.board.custom6_type_len = type_length;
alter_field_content(&fruid.board.custom6,tmp_content);
break;
case PM:
fruid.product.mfg_type_len = type_length;
alter_field_content(&fruid.product.mfg,tmp_content);
break;
case PN:
fruid.product.name_type_len = type_length;
alter_field_content(&fruid.product.name,tmp_content);
break;
case PPN:
fruid.product.part_type_len = type_length;
alter_field_content(&fruid.product.part,tmp_content);
break;
case PV:
fruid.product.version_type_len = type_length;
alter_field_content(&fruid.product.version,tmp_content);
break;
case PSN:
fruid.product.serial_type_len = type_length;
alter_field_content(&fruid.product.serial,tmp_content);
break;
case PAT:
fruid.product.asset_tag_type_len = type_length;
alter_field_content(&fruid.product.asset_tag,tmp_content);
break;
case PFI:
fruid.product.fruid_type_len = type_length;
alter_field_content(&fruid.product.fruid,tmp_content);
break;
case PCD1:
fruid.product.custom1_type_len = type_length;
alter_field_content(&fruid.product.custom1,tmp_content);
break;
case PCD2:
if (fruid.product.custom1_type_len == NO_MORE_DATA_BYTE)
fruid.product.custom1_type_len = 0;
fruid.product.custom2_type_len = type_length;
alter_field_content(&fruid.product.custom2,tmp_content);
break;
case PCD3:
if (fruid.product.custom1_type_len == NO_MORE_DATA_BYTE)
fruid.product.custom1_type_len = 0;
if (fruid.product.custom2_type_len == NO_MORE_DATA_BYTE)
fruid.product.custom2_type_len = 0;
fruid.product.custom3_type_len = type_length;
alter_field_content(&fruid.product.custom3,tmp_content);
break;
case PCD4:
if (fruid.product.custom1_type_len == NO_MORE_DATA_BYTE)
fruid.product.custom1_type_len = 0;
if (fruid.product.custom2_type_len == NO_MORE_DATA_BYTE)
fruid.product.custom2_type_len = 0;
if (fruid.product.custom3_type_len == NO_MORE_DATA_BYTE)
fruid.product.custom3_type_len = 0;
fruid.product.custom4_type_len = type_length;
alter_field_content(&fruid.product.custom4,tmp_content);
break;
case PCD5:
if (fruid.product.custom1_type_len == NO_MORE_DATA_BYTE)
fruid.product.custom1_type_len = 0;
if (fruid.product.custom2_type_len == NO_MORE_DATA_BYTE)
fruid.product.custom2_type_len = 0;
if (fruid.product.custom3_type_len == NO_MORE_DATA_BYTE)
fruid.product.custom3_type_len = 0;
if (fruid.product.custom4_type_len == NO_MORE_DATA_BYTE)
fruid.product.custom4_type_len = 0;
fruid.product.custom5_type_len = type_length;
alter_field_content(&fruid.product.custom5,tmp_content);
break;
case PCD6:
if (fruid.product.custom1_type_len == NO_MORE_DATA_BYTE)
fruid.product.custom1_type_len = 0;
if (fruid.product.custom2_type_len == NO_MORE_DATA_BYTE)
fruid.product.custom2_type_len = 0;
if (fruid.product.custom3_type_len == NO_MORE_DATA_BYTE)
fruid.product.custom3_type_len = 0;
if (fruid.product.custom4_type_len == NO_MORE_DATA_BYTE)
fruid.product.custom4_type_len = 0;
if (fruid.product.custom5_type_len == NO_MORE_DATA_BYTE)
fruid.product.custom5_type_len = 0;
fruid.product.custom6_type_len = type_length;
alter_field_content(&fruid.product.custom6,tmp_content);
break;
default:
return -1;
break;
}
// create new FRU alloc new eeprom
// We need the existing length + length of new content, but we can also add
// new optional fields (for instance if custom1 is added, the others become 0
// byte fields, but with a type/len byte). For safety add enough bytes to
// cover all the optional fields to prevent buffer overruns. We track the
// number of bytes added to the array, so only that number will be written to
// the eeprom.
new_fruid_len = fruid_len + ((content_len / 8) + 1) * 8 + total_field_opt_size;
eeprom = (uint8_t *) malloc(new_fruid_len);
memset(eeprom, 0, new_fruid_len);
if (!eeprom) {
#ifdef DEBUG
syslog(LOG_WARNING, "%s: malloc: memory allocation failed", __func__);
#endif
return ENOMEM;
}
// chassis area
i = 8;
len = 0;
int start = i;
if (fruid.chassis.flag == 1) {
eeprom[i++] = fruid.chassis.format_ver;
eeprom[i++] = fruid.chassis.area_len;
eeprom[i++] = fruid.chassis.type;
eeprom[i++] = fruid.chassis.part_type_len;
len = FIELD_LEN(fruid.chassis.part_type_len);
memcpy(&eeprom[i], fruid.chassis.part, len);
i += len;
eeprom[i++] = fruid.chassis.serial_type_len;
len = FIELD_LEN(fruid.chassis.serial_type_len);
memcpy(&eeprom[i], fruid.chassis.serial, len);
i += len;
eeprom[i++] = fruid.chassis.custom1_type_len;
if (fruid.chassis.custom1_type_len == NO_MORE_DATA_BYTE)
goto chasis_chksum;
len = FIELD_LEN(fruid.chassis.custom1_type_len);
memcpy(&eeprom[i], fruid.chassis.custom1, len);
i += len;
eeprom[i++] = fruid.chassis.custom2_type_len;
if (fruid.chassis.custom2_type_len == NO_MORE_DATA_BYTE)
goto chasis_chksum;
len = FIELD_LEN(fruid.chassis.custom2_type_len);
memcpy(&eeprom[i], fruid.chassis.custom2, len);
i += len;
eeprom[i++] = fruid.chassis.custom3_type_len;
if (fruid.chassis.custom3_type_len == NO_MORE_DATA_BYTE)
goto chasis_chksum;
len = FIELD_LEN(fruid.chassis.custom3_type_len);
memcpy(&eeprom[i], fruid.chassis.custom3, len);
i += len;
eeprom[i++] = fruid.chassis.custom4_type_len;
if (fruid.chassis.custom4_type_len == NO_MORE_DATA_BYTE)
goto chasis_chksum;
len = FIELD_LEN(fruid.chassis.custom4_type_len);
memcpy(&eeprom[i], fruid.chassis.custom4, len);
i += len;
eeprom[i++] = fruid.chassis.custom5_type_len;
if (fruid.chassis.custom5_type_len == NO_MORE_DATA_BYTE)
goto chasis_chksum;
len = FIELD_LEN(fruid.chassis.custom5_type_len);
memcpy(&eeprom[i], fruid.chassis.custom5, len);
i += len;
eeprom[i++] = fruid.chassis.custom6_type_len;
if (fruid.chassis.custom6_type_len == NO_MORE_DATA_BYTE)
goto chasis_chksum;
len = FIELD_LEN(fruid.chassis.custom6_type_len);
memcpy(&eeprom[i], fruid.chassis.custom6, len);
i += len;
chasis_chksum:
if (eeprom[i - 1] != NO_MORE_DATA_BYTE) {
eeprom[i++] = NO_MORE_DATA_BYTE;
}
i += (7 - (i % 8));
fruid.chassis.area_len = i - start + 1;
eeprom[start + 1] = fruid.chassis.area_len / FRUID_AREA_LEN_MULTIPLIER;
ret = calculate_chksum(&eeprom[start], fruid.chassis.area_len);
if (ret < 0) {
printf("Update chassis checksum fail!\n");
goto error_exit;
}
i++;
} else {
fruid.chassis.area_len = 0;
}
// board area
start = i;
if (fruid.board.flag == 1) {
eeprom[i++] = fruid.board.format_ver;
eeprom[i++] = fruid.board.area_len;
eeprom[i++] = fruid.board.lang_code;
memcpy(&eeprom[i], fruid.board.mfg_time, 3);
i += 3;
eeprom[i++] = fruid.board.mfg_type_len;
len = FIELD_LEN(fruid.board.mfg_type_len);
memcpy(&eeprom[i], fruid.board.mfg, len);
i += len;
eeprom[i++] = fruid.board.name_type_len;
len = FIELD_LEN(fruid.board.name_type_len);
memcpy(&eeprom[i], fruid.board.name, len);
i += len;
eeprom[i++] = fruid.board.serial_type_len;
len = FIELD_LEN(fruid.board.serial_type_len);
memcpy(&eeprom[i], fruid.board.serial, len);
i += len;
eeprom[i++] = fruid.board.part_type_len;
len = FIELD_LEN(fruid.board.part_type_len);
memcpy(&eeprom[i], fruid.board.part, len);
i += len;
eeprom[i++] = fruid.board.fruid_type_len;
len = FIELD_LEN(fruid.board.fruid_type_len);
memcpy(&eeprom[i], fruid.board.fruid, len);
i += len;
eeprom[i++] = fruid.board.custom1_type_len;
if (fruid.board.custom1_type_len == NO_MORE_DATA_BYTE)
goto board_chksum;
len = FIELD_LEN(fruid.board.custom1_type_len);
memcpy(&eeprom[i], fruid.board.custom1, len);
i += len;
eeprom[i++] = fruid.board.custom2_type_len;
if (fruid.board.custom2_type_len == NO_MORE_DATA_BYTE)
goto board_chksum;
len = FIELD_LEN(fruid.board.custom2_type_len);
memcpy(&eeprom[i], fruid.board.custom2, len);
i += len;
eeprom[i++] = fruid.board.custom3_type_len;
if (fruid.board.custom3_type_len == NO_MORE_DATA_BYTE)
goto board_chksum;
len = FIELD_LEN(fruid.board.custom3_type_len);
memcpy(&eeprom[i], fruid.board.custom3, len);
i += len;
eeprom[i++] = fruid.board.custom4_type_len;
if (fruid.board.custom4_type_len == NO_MORE_DATA_BYTE)
goto board_chksum;
len = FIELD_LEN(fruid.board.custom4_type_len);
memcpy(&eeprom[i], fruid.board.custom4, len);
i += len;
eeprom[i++] = fruid.board.custom5_type_len;
if (fruid.board.custom5_type_len == NO_MORE_DATA_BYTE)
goto board_chksum;
len = FIELD_LEN(fruid.board.custom5_type_len);
memcpy(&eeprom[i], fruid.board.custom5, len);
i += len;
eeprom[i++] = fruid.board.custom6_type_len;
if (fruid.board.custom6_type_len == NO_MORE_DATA_BYTE)
goto board_chksum;
len = FIELD_LEN(fruid.board.custom6_type_len);
memcpy(&eeprom[i], fruid.board.custom6, len);
i += len;
board_chksum:
if (eeprom[i - 1] != NO_MORE_DATA_BYTE) {
eeprom[i++] = NO_MORE_DATA_BYTE;
}
i += (7 - (i % 8));
fruid.board.area_len = i - start + 1;
eeprom[start + 1] = fruid.board.area_len / FRUID_AREA_LEN_MULTIPLIER;
ret = calculate_chksum(&eeprom[start], fruid.board.area_len);
if (ret < 0) {
printf("Update board checksum fail!\n");
goto error_exit;
}
i++;
} else {
fruid.board.area_len = 0;
}
// product area
start = i;
if (fruid.product.flag == 1) {
eeprom[i++] = fruid.product.format_ver;
eeprom[i++] = fruid.product.area_len;
eeprom[i++] = fruid.product.lang_code;
eeprom[i++] = fruid.product.mfg_type_len;
len = FIELD_LEN(fruid.product.mfg_type_len);
memcpy(&eeprom[i], fruid.product.mfg, len);
i += len;
eeprom[i++] = fruid.product.name_type_len;
len = FIELD_LEN(fruid.product.name_type_len);
memcpy(&eeprom[i], fruid.product.name, len);
i += len;
eeprom[i++] = fruid.product.part_type_len;
len = FIELD_LEN(fruid.product.part_type_len);
memcpy(&eeprom[i], fruid.product.part, len);
i += len;
eeprom[i++] = fruid.product.version_type_len;
len = FIELD_LEN(fruid.product.version_type_len);
memcpy(&eeprom[i], fruid.product.version, len);
i += len;
eeprom[i++] = fruid.product.serial_type_len;
len = FIELD_LEN(fruid.product.serial_type_len);
memcpy(&eeprom[i], fruid.product.serial, len);
i += len;
eeprom[i++] = fruid.product.asset_tag_type_len;
len = FIELD_LEN(fruid.product.asset_tag_type_len);
memcpy(&eeprom[i], fruid.product.asset_tag, len);
i += len;
eeprom[i++] = fruid.product.fruid_type_len;
len = FIELD_LEN(fruid.product.fruid_type_len);
memcpy(&eeprom[i], fruid.product.fruid, len);
i += len;
eeprom[i++] = fruid.product.custom1_type_len;
if (fruid.product.custom1_type_len == NO_MORE_DATA_BYTE)
goto product_chksum;
len = FIELD_LEN(fruid.product.custom1_type_len);
memcpy(&eeprom[i], fruid.product.custom1, len);
i += len;
eeprom[i++] = fruid.product.custom2_type_len;
if (fruid.product.custom2_type_len == NO_MORE_DATA_BYTE)
goto product_chksum;
len = FIELD_LEN(fruid.product.custom2_type_len);
memcpy(&eeprom[i], fruid.product.custom2, len);
i += len;
eeprom[i++] = fruid.product.custom3_type_len;
if (fruid.product.custom3_type_len == NO_MORE_DATA_BYTE)
goto product_chksum;
len = FIELD_LEN(fruid.product.custom3_type_len);
memcpy(&eeprom[i], fruid.product.custom3, len);
i += len;
eeprom[i++] = fruid.product.custom4_type_len;
if (fruid.product.custom4_type_len == NO_MORE_DATA_BYTE)
goto product_chksum;
len = FIELD_LEN(fruid.product.custom4_type_len);
memcpy(&eeprom[i], fruid.product.custom4, len);
i += len;
eeprom[i++] = fruid.product.custom5_type_len;
if (fruid.product.custom5_type_len == NO_MORE_DATA_BYTE)
goto product_chksum;
len = FIELD_LEN(fruid.product.custom5_type_len);
memcpy(&eeprom[i], fruid.product.custom5, len);
i += len;
eeprom[i++] = fruid.product.custom6_type_len;
if (fruid.product.custom6_type_len == NO_MORE_DATA_BYTE)
goto product_chksum;
len = FIELD_LEN(fruid.product.custom6_type_len);
memcpy(&eeprom[i], fruid.product.custom6, len);
i += len;
product_chksum:
if (eeprom[i - 1] != NO_MORE_DATA_BYTE) {
eeprom[i++] = NO_MORE_DATA_BYTE;
}
i += (7 - (i % 8));
fruid.product.area_len = i - start + 1;
eeprom[start + 1] = fruid.product.area_len / FRUID_AREA_LEN_MULTIPLIER;
ret = calculate_chksum(&eeprom[start], fruid.product.area_len);
if (ret < 0) {
printf("Update product checksum fail!\n");
goto error_exit;
}
i++;
} else {
fruid.product.area_len = 0;
}
// update header
int offset = 1;
eeprom[0] = 0x01; // format version
if (fruid.chassis.flag == 1) {
eeprom[2] = offset; // chassis area offset
}
if (fruid.board.flag == 1) {
offset += fruid.chassis.area_len / FRUID_AREA_LEN_MULTIPLIER; // board area offset
eeprom[3] = offset;
}
if (fruid.product.flag == 1) {
offset += fruid.board.area_len / FRUID_AREA_LEN_MULTIPLIER; // product area offset
eeprom[4] = offset;
}
// update header checksum
ret = calculate_chksum(&eeprom[0], 8);
if (ret < 0) {
printf("Update header checksum fail!\n");
goto error_exit;
}
/* Open the FRUID binary file */
fruid_fd = fopen(new_bin, "wb");
if (!fruid_fd) {
#ifdef DEBUG
syslog(LOG_ERR, "%s: unable to open the file %s", __func__, new_bin);
#endif
return ENOENT;
}
/* Write the binary file */
fwrite(eeprom, sizeof(uint8_t), i, fruid_fd);
/* Close the FRUID binary file */
fclose(fruid_fd);
error_exit:
/* Free the eeprom malloced memory */
free(eeprom);
/* Free the malloced memory for the fruid information */
free_fruid_info(&fruid);
return ret;
}