ipmi_fru_set_field_string(struct ipmi_intf * intf, uint8_t fruId, uint8_t
f_type, uint8_t f_index, char *f_string)
{
	struct ipmi_rs *rsp;
	struct ipmi_rq req;

	struct fru_info fru;
	struct fru_header header;
	uint8_t msg_data[4];
	uint8_t checksum;
	int i = 0;
	int rc = 1;
	uint8_t *fru_data = NULL;
	uint8_t *fru_area = NULL;
	uint32_t fru_field_offset, fru_field_offset_tmp;
	uint32_t fru_section_len, header_offset;

	memset(msg_data, 0, 4);
	msg_data[0] = fruId;

	memset(&req, 0, sizeof(req));
	req.msg.netfn = IPMI_NETFN_STORAGE;
	req.msg.cmd = GET_FRU_INFO;
	req.msg.data = msg_data;
	req.msg.data_len = 1;

	rsp = intf->sendrecv(intf, &req);
	if (!rsp) {
		printf(" Device not present (No Response)\n");
		rc = -1;
		goto ipmi_fru_set_field_string_out;
	}
	if (rsp->ccode) {
		printf(" Device not present (%s)\n",
			val2str(rsp->ccode, completion_code_vals));
		rc = -1;
		goto ipmi_fru_set_field_string_out;
	}

	memset(&fru, 0, sizeof(fru));
	fru.size = (rsp->data[1] << 8) | rsp->data[0];
	fru.access = rsp->data[2] & 0x1;

	if (fru.size < 1) {
		printf(" Invalid FRU size %d", fru.size);
		rc = -1;
		goto ipmi_fru_set_field_string_out;
	}
	/*
	* retrieve the FRU header
	*/
	msg_data[0] = fruId;
	msg_data[1] = 0;
	msg_data[2] = 0;
	msg_data[3] = 8;

	memset(&req, 0, sizeof(req));
	req.msg.netfn = IPMI_NETFN_STORAGE;
	req.msg.cmd = GET_FRU_DATA;
	req.msg.data = msg_data;
	req.msg.data_len = 4;

	rsp = intf->sendrecv(intf, &req);
	if (!rsp)
	{
		printf(" Device not present (No Response)\n");
		rc = -1;
		goto ipmi_fru_set_field_string_out;
	}
	if (rsp->ccode)
	{
		printf(" Device not present (%s)\n",
				val2str(rsp->ccode, completion_code_vals));
		rc = -1;
		goto ipmi_fru_set_field_string_out;
	}

	if (verbose > 1)
		printbuf(rsp->data, rsp->data_len, "FRU DATA");

	memcpy(&header, rsp->data + 1, 8);

	if (header.version != 1) {
		printf(" Unknown FRU header version 0x%02x",
			header.version);
		rc = -1;
		goto ipmi_fru_set_field_string_out;
	}

	fru_data = malloc( fru.size );
	if (!fru_data) {
		printf("Out of memory!\n");
		rc = -1;
		goto ipmi_fru_set_field_string_out;
	}

	/* Setup offset from the field type */

	/* Chassis type field */
	if (f_type == 'c' ) {
		header_offset = (header.offset.chassis * 8);
		read_fru_area(intf ,&fru, fruId, header_offset , 3 , fru_data);
		fru_field_offset = 3;
		fru_section_len = *(fru_data + 1) * 8;
	}
	/* Board type field */
	else if (f_type == 'b' ) {
		header_offset = (header.offset.board * 8);
		read_fru_area(intf ,&fru, fruId, header_offset , 3 , fru_data);
		fru_field_offset = 6;
		fru_section_len = *(fru_data + 1) * 8;
	}
	/* Product type field */
	else if (f_type == 'p' ) {
		header_offset = (header.offset.product * 8);
		read_fru_area(intf ,&fru, fruId, header_offset , 3 , fru_data);
		fru_field_offset = 3;
		fru_section_len = *(fru_data + 1) * 8;
	}
	else
	{
		printf("Wrong field type.");
		rc = -1;
		goto ipmi_fru_set_field_string_out;
	}
	memset(fru_data, 0, fru.size);
	if( read_fru_area(intf ,&fru, fruId, header_offset ,
					fru_section_len , fru_data) < 0 )
	{
		rc = -1;
		goto ipmi_fru_set_field_string_out;
	}
	/* Convert index from character to decimal */
	f_index= f_index - 0x30;

	/*Seek to field index */
	for (i=0; i <= f_index; i++) {
		fru_field_offset_tmp = fru_field_offset;
		if (fru_area) {
			free_n(&fru_area);
		}
		fru_area = (uint8_t *) get_fru_area_str(fru_data, &fru_field_offset);
	}

	if (!FRU_FIELD_VALID(fru_area)) {
		printf("Field not found !\n");
		rc = -1;
		goto ipmi_fru_set_field_string_out;
	}

	if ( strlen((const char *)fru_area) == strlen((const char *)f_string) )
	{
		printf("Updating Field '%s' with '%s' ...\n", fru_area, f_string );
		memcpy(fru_data + fru_field_offset_tmp + 1,
								f_string, strlen(f_string));

		checksum = 0;
		/* Calculate Header Checksum */
		for (i = 0; i < fru_section_len - 1; i++)
		{
			checksum += fru_data[i];
		}
		checksum = (~checksum) + 1;
		fru_data[fru_section_len - 1] = checksum;

		/* Write the updated section to the FRU data; source offset => 0 */
		if( write_fru_area(intf, &fru, fruId, 0,
				header_offset, fru_section_len, fru_data) < 0 )
		{
			printf("Write to FRU data failed.\n");
			rc = -1;
			goto ipmi_fru_set_field_string_out;
		}
	}
	else {
		printf("String size are not equal, resizing fru to fit new string\n");
		if(
				ipmi_fru_set_field_string_rebuild(intf,fruId,fru,header,f_type,f_index,f_string)
		)
		{
			rc = -1;
			goto ipmi_fru_set_field_string_out;
		}
	}

ipmi_fru_set_field_string_out:
	free_n(&fru_data);
	free_n(&fru_area);

	return rc;
}