ipmi_fru_oemkontron_edit( int argc, char ** argv,uint8_t * fru_data,
												int off,int len,
												struct fru_multirec_header *h,
												struct fru_multirec_oem_header *oh)
{
	static bool badParams=false;
	bool hasChanged = false;
	int start = off;
	int offset = start;
	int length = len;
	int i;
	uint8_t record_id = 0;
	offset += sizeof(struct fru_multirec_oem_header);

	if(!badParams){
		/* the 'OEM' field is already checked in caller */
		if( argc > OEM_KONTRON_SUBCOMMAND_ARG_POS ){
			if(strncmp("oem", argv[OEM_KONTRON_SUBCOMMAND_ARG_POS],3)){
				printf("usage: fru edit <id> <oem> <args...>\n");
				badParams = true;
				return hasChanged;
			}
		}
		if( argc<EDIT_OEM_KONTRON_COMPLETE_ARG_COUNT ){
			printf("usage: oem <iana> <recordid> <format> <args...>\n");
			printf("usage: oem 15000 3 0 <name> <instance> <field1>"\
					" <field2> <field3> <crc32>\n");
			badParams = true;
			return hasChanged;
		}
		if (str2uchar(argv[OEM_KONTRON_RECORDID_ARG_POS], &record_id) != 0) {
			lprintf(LOG_ERR,
					"Record ID argument '%s' is either invalid or out of range.",
					argv[OEM_KONTRON_RECORDID_ARG_POS]);
			badParams = true;
			return hasChanged;
		}
		if (record_id == OEM_KONTRON_INFORMATION_RECORD) {
			for(i=OEM_KONTRON_VERSION_ARG_POS;i<=OEM_KONTRON_CRC32_ARG_POS;i++){
				if( (strlen(argv[i]) != OEM_KONTRON_FIELD_SIZE) &&
					(strlen(argv[i]) != OEM_KONTRON_VERSION_FIELD_SIZE)) {
					printf("error: version fields must have %d characters\n",
										OEM_KONTRON_FIELD_SIZE);
					badParams = true;
					return hasChanged;
				}
			}
		}
	}

	if(!badParams){

		if(oh->record_id == OEM_KONTRON_INFORMATION_RECORD ) {
			uint8_t formatVersion = 0;
			uint8_t version;

			if (str2uchar(argv[OEM_KONTRON_FORMAT_ARG_POS], &formatVersion) != 0) {
				lprintf(LOG_ERR,
						"Format argument '%s' is either invalid or out of range.",
						argv[OEM_KONTRON_FORMAT_ARG_POS]);
				badParams = true;
				return hasChanged;
			}

			printf("   Kontron OEM Information Record\n");
			version = oh->record_version;

			if( version == formatVersion  ){
				uint8_t blockCount;
				uint8_t blockIndex=0;

				uint8_t matchInstance = 0;
				uint8_t instance = 0;
				
				if (str2uchar(argv[OEM_KONTRON_INSTANCE_ARG_POS], &instance) != 0) {
					lprintf(LOG_ERR,
							"Instance argument '%s' is either invalid or out of range.",
							argv[OEM_KONTRON_INSTANCE_ARG_POS]);
					badParams = true;
					return hasChanged;
				}

				blockCount = fru_data[offset++];
				printf("   blockCount: %d\n",blockCount);

				for(blockIndex=0;blockIndex<blockCount;blockIndex++){
					void * pRecordData;
					uint8_t nameLen;

					nameLen = ( fru_data[offset++] & 0x3F );

					if( version == 0 || version == 1 )
					{
						if(!strncmp((char *)argv[OEM_KONTRON_NAME_ARG_POS],
						(const char *)(fru_data+offset),nameLen)&& (matchInstance == instance)){

							printf ("Found : %s\n",argv[OEM_KONTRON_NAME_ARG_POS]);
							offset+=nameLen;

							pRecordData =  &fru_data[offset];

							if( version == 0 )
							{
								memcpy( ((tOemKontronInformationRecordV0 *)
															pRecordData)->field1 ,
								argv[OEM_KONTRON_VERSION_ARG_POS] ,
								OEM_KONTRON_FIELD_SIZE);
								memcpy( ((tOemKontronInformationRecordV0 *)
															pRecordData)->field2 ,
								argv[OEM_KONTRON_BUILDDATE_ARG_POS],
								OEM_KONTRON_FIELD_SIZE);
								memcpy( ((tOemKontronInformationRecordV0 *)
															pRecordData)->field3 ,
								argv[OEM_KONTRON_UPDATEDATE_ARG_POS],
								OEM_KONTRON_FIELD_SIZE);
								memcpy( ((tOemKontronInformationRecordV0 *)
															pRecordData)->crc32 ,
							argv[OEM_KONTRON_CRC32_ARG_POS] ,
							OEM_KONTRON_FIELD_SIZE);
							}
							else
							{
								memcpy( ((tOemKontronInformationRecordV1 *)
															pRecordData)->field1 ,
								argv[OEM_KONTRON_VERSION_ARG_POS] ,
								OEM_KONTRON_VERSION_FIELD_SIZE);
								memcpy( ((tOemKontronInformationRecordV1 *)
															pRecordData)->field2 ,
								argv[OEM_KONTRON_BUILDDATE_ARG_POS],
								OEM_KONTRON_FIELD_SIZE);
								memcpy( ((tOemKontronInformationRecordV1 *)
															pRecordData)->field3 ,
								argv[OEM_KONTRON_UPDATEDATE_ARG_POS],
								OEM_KONTRON_FIELD_SIZE);
								memcpy( ((tOemKontronInformationRecordV1 *)
															pRecordData)->crc32 ,
							argv[OEM_KONTRON_CRC32_ARG_POS] ,
							OEM_KONTRON_FIELD_SIZE);
							}

							matchInstance++;
							hasChanged = true;
						}
						else if(!strncmp((char *)argv[OEM_KONTRON_NAME_ARG_POS],
							(const char *)(fru_data+offset), nameLen)){
							printf ("Skipped : %s  [instance %d]\n",argv[OEM_KONTRON_NAME_ARG_POS],
									(unsigned int)matchInstance);
							matchInstance++;
							offset+=nameLen;
						}
						else {
							offset+=nameLen;
						}

						if( version == 0 )
						{
							offset+= sizeof(tOemKontronInformationRecordV0);
						}
						else
						{
							offset+= sizeof(tOemKontronInformationRecordV1);
						}
						offset++;
					}
					else
					{
						printf ("  Unsupported version %d\n",version);
					}
				}
			}
			else{
				printf("   Version: %d\n",version);
			}
		}
		if( hasChanged ){

			uint8_t record_checksum =0;
			uint8_t header_checksum =0;
			int index;

			lprintf(LOG_DEBUG,"Initial record checksum : %x",h->record_checksum);
			lprintf(LOG_DEBUG,"Initial header checksum : %x",h->header_checksum);
			for(index=0;index<length;index++){
				record_checksum+=  fru_data[start+index];
			}
			/* Update Record checksum */
			h->record_checksum =  ~record_checksum + 1;


			for(index=0;index<(sizeof(struct fru_multirec_header) -1);index++){
				uint8_t data= *( (uint8_t *)h+ index);
				header_checksum+=data;
			}
			/* Update header checksum */
			h->header_checksum =  ~header_checksum + 1;

			lprintf(LOG_DEBUG,"Final record checksum : %x",h->record_checksum);
			lprintf(LOG_DEBUG,"Final header checksum : %x",h->header_checksum);

			/* write back data */
		}
	}

	return hasChanged;
}