/// <summary> /// Write Fru Data Command. Note: /// The command writes the specified byte or word to the FRU Inventory Info area. This is a ‘low level’ direct /// interface to a non-volatile storage area. The interface does not interpret or check any semantics or /// formatting for the data being written. The offset used in this command is a ‘logical’ offset that may or may not /// correspond to the physical address. For example, FRU information could be kept in FLASH at physical address 1234h, /// however offset 0000h would still be used with this command to access the start of the FRU information. /// /// IPMI FRU device data (devices that are formatted per [FRU]) as well as processor and DIMM FRU data always starts /// from offset 0000h unless otherwise noted. /// </summary> public virtual WriteFruDevice WriteFruDevice(int deviceId, ushort offset, byte[] payload) { byte loOffset; byte hiOffset; // split address into hi and lo bytes. IpmiSharedFunc.SplitWord(offset, out loOffset, out hiOffset); WriteFruDataResponse fruResponse = this.IpmiSendReceive <WriteFruDataResponse>(new WriteFruDataRequest(loOffset, hiOffset, payload) { DeviceId = (byte)deviceId }); WriteFruDevice response = new WriteFruDevice(fruResponse.CompletionCode); if (fruResponse.CompletionCode == 0) { response.SetParamaters(new byte[1] { fruResponse.CountWritten }); } return(response); }
/// <summary> /// Reads raw fru data, and returns a byte array. /// </summary> public virtual byte[] ReadFruDevice(int deviceId, ushort offset, byte readCount) { byte loOffset; byte hiOffset; // split address into hi and lo bytes. IpmiSharedFunc.SplitWord(offset, out loOffset, out hiOffset); GetFruDataResponse fruResponse = this.IpmiSendReceive <GetFruDataResponse>(new GetFruDataRequest(loOffset, hiOffset, readCount) { DeviceId = (byte)deviceId }); return(fruResponse.DataReturned); }
/// <summary> /// Returns a byte array with all bytes from a specific area of the fru: Chassis, Baseboard, Product /// </summary> private byte[] ReadFruAreaBytes(int deviceId, ushort offset, bool maxLenght, out byte completionCode) { byte countToRead = 0x10; byte loOffset; byte hiOffset; List <byte> areaBytes = new List <byte>(); IpmiSharedFunc.SplitWord(offset, out loOffset, out hiOffset); ushort totalDataRead = countToRead; GetFruDataRequest fruRequest = new GetFruDataRequest(loOffset, hiOffset, countToRead) { DeviceId = (byte)deviceId }; GetFruDataResponse fruResponse = IpmiSendReceive <GetFruDataResponse>(fruRequest); completionCode = fruResponse.CompletionCode; if (completionCode == 0x00) { ushort dataSize = FruArea.AreaLength(fruResponse.DataReturned); totalDataRead = Math.Min(countToRead, dataSize); IpmiSharedFunc.AppendArrayToList(fruResponse.DataReturned, areaBytes, totalDataRead); offset += totalDataRead; int pass = 0; while (dataSize > totalDataRead || pass > 12) { IpmiSharedFunc.SplitWord(offset, out loOffset, out hiOffset); if (!maxLenght) { countToRead = (byte)Math.Min(countToRead, dataSize - totalDataRead); } else { countToRead = (byte)Math.Min(byte.MaxValue, dataSize - totalDataRead); } fruRequest = new GetFruDataRequest(loOffset, hiOffset, countToRead) { DeviceId = (byte)deviceId }; // send request for more data fruResponse = IpmiSendReceive <GetFruDataResponse>(fruRequest); totalDataRead += countToRead; offset += countToRead; completionCode = fruResponse.CompletionCode; if (completionCode == 0x00) { IpmiSharedFunc.AppendArrayToList(fruResponse.DataReturned, areaBytes, countToRead); } else { break; } pass++; } if (pass > 12) { completionCode = 0xEF; } } return(areaBytes.ToArray()); }