/// <summary> /// Formats Time Stamped OEM SEL Records /// </summary> /// <param name="EventMessageData">Event Message Data</param> /// <param name="RecordCount">SEL Record Type</param> internal static void TimeStampedOEMSelFormat(ref SystemEventLogMessage message, byte[] messageData) { // convert byte[] to int using Shift operation int TotalSeconds = messageData[0] + (messageData[1] << 8) + (messageData[2] << 16) + (messageData[3] << 24); // calculate Recorded date message.EventDate = IpmiSharedFunc.SecondsOffSet(TotalSeconds); message.EventVersion = MsgVersion.OEM; // SensorType, RawSensorType and EventTypeCode are not used for OEM SEL entries message.SensorType = SensorType.Reserved; message.RawSensorType = (byte)SensorType.Reserved; message.EventTypeCode = 0xFF; message.SensorNumber = 0; message.EventDir = EventDir.Assertion; if (messageData.Length >= 13) { // Allocate larger array to store OEM Timestamped payload message.RawPayload = new byte[9]; // Copy Manufacturer ID and OEM Defined payload to the response raw payload array. Format shown in IPMI 2.0 Spec Table 32-2. Buffer.BlockCopy(messageData, 4, message.RawPayload, 0, 9); // Add the raw payload as hex string to the user return class. message.EventPayload = IpmiSharedFunc.ByteArrayToHexString(message.RawPayload); } }
/// <summary> /// Formats Non Time Stamped OEM SEL Records /// </summary> /// <param name="EventMessageData">Event Message Data</param> /// <param name="RecordCount">SEL Record Type</param> internal static void NonTimestampedOemSelFormat(ref SystemEventLogMessage message, byte[] messageData) { // calculate Recorded date message.EventDate = new DateTime(0000, 0, 0); message.EventVersion = MsgVersion.OEM; // SensorType, RawSensorType and EventTypeCode are not used for OEM SEL entries message.SensorType = SensorType.Reserved; message.RawSensorType = (byte)SensorType.Reserved; message.EventTypeCode = 0xFF; message.SensorNumber = 0; message.EventDir = EventDir.Assertion; if (messageData.Length >= 13) { // Allocate larger array to store OEM Non-timestamped payload message.RawPayload = new byte[13]; // Copy OEM Defined payload to the response raw payload array. Format shown in IPMI 2.0 Spec Table 32-3. Buffer.BlockCopy(messageData, 0, message.RawPayload, 0, 13); // Add the raw payload as hex string to the user return class. message.EventPayload = IpmiSharedFunc.ByteArrayToHexString(message.RawPayload); } }
/// <summary> /// Formats System Event (Standard Range) SEL Records /// </summary> /// <param name="EventMessageData">Event Message Data</param> /// <param name="RecordCount">SEL Record Type</param> internal static void StandardSelFormat(ref SystemEventLogMessage message, byte[] messageData) { // convert data bytes from messageData byte[] to int using Shift operation int totalSeconds = TimeStampFromBytes(messageData); // calculate Recorded date message.EventDate = IpmiSharedFunc.SecondsOffSet(totalSeconds); // SEL Event Message if (Enum.IsDefined(typeof(MsgVersion), messageData[6])) { message.EventVersion = (MsgVersion)messageData[6]; } else { message.EventVersion = MsgVersion.Unknown; } // Sensor Type byte sensorType = messageData[7]; // add sensor type to attribute class if (Enum.IsDefined(typeof(SensorType), sensorType)) { message.SensorType = (SensorType)sensorType; } else { message.SensorType = SensorType.Unknown; } // add sensor type to message message.RawSensorType = messageData[7]; // add sensor number to the message class message.SensorNumber = messageData[8]; // Event Data Byte byte[] eventDataByte = IpmiSharedFunc.ByteSplit(messageData[9], new int[2] { 7, 0 }); // Event Dir. Asersion/Deserstion Bit 7 byte eventDir = eventDataByte[0]; // EventType [6:0] byte eventTypeCode = eventDataByte[1]; message.EventTypeCode = eventTypeCode; // Event Dir if (Enum.IsDefined(typeof(EventDir), eventDir)) { message.EventDir = (EventDir)eventDir; } else { message.EventDir = EventDir.Unknown; } // copy event message payload to the response raw payload array Buffer.BlockCopy(messageData, 10, message.RawPayload, 0, 3); // Add the raw payload as hex string to the user return class. message.EventPayload = IpmiSharedFunc.ByteArrayToHexString(message.RawPayload); }
/// <summary> /// Recursively retrieves System Event Log entries. /// </summary> public virtual SystemEventLog GetSel() { // return value. create string collection to hold system event strings. SystemEventLog messageCollection = new SystemEventLog(0x00); // Default Record Off Set byte offSet = 0x00; // limit number of records to retrive ushort RecordCount = 0; // limit number of records to retrive ushort RecordLimit = 350; // system event log entry point ushort recordId = 0; // system event log record reserve (used for partial retrieve) ushort reserveId = 0; // signal last system event record (aborts event log Loop) ushort lastRecordId = 65535; // system event log record Id and raw payload collection IpmiSelCollection responseCollection = new IpmiSelCollection(); // retrieve all records while connected by recursively calling the Sel entry command while (recordId != lastRecordId || RecordCount >= RecordLimit) { // get the SEL record SelEntryResponse response = (SelEntryResponse)this.IpmiSendReceive( new SelEntryRequest(reserveId, recordId, offSet), typeof(SelEntryResponse)); // reset the main class error code. messageCollection.CompletionCode = response.CompletionCode; if (response.CompletionCode == 0x00) { // add the record to the collection responseCollection.Add(response); // update the record Id (signals loop exit) recordId = BitConverter.ToUInt16(response.NextRecordId, 0); } else { // add the errored record to the collection responseCollection.Add(response); // break the loop on error. break; } RecordCount++; } // check for valid sel event messages before processing if (responseCollection.Count > 0) { foreach (SelEntryResponse response in responseCollection) { SystemEventLogMessage message = new SystemEventLogMessage(response.CompletionCode); // if the response was not an error cast it. if (response.CompletionCode == 0x00) { // bytes 0-2 = Record Id ushort recordNo = BitConverter.ToUInt16(response.SelEntry, 0); // sel record type byte recordType = response.SelEntry[2]; // byte array for message data byte[] messageData = new byte[13]; // copy message data in message data array Buffer.BlockCopy(response.SelEntry, 3, messageData, 0, (response.SelEntry.Length - 3)); // IPMI SPEC: 31.6.1 SEL Record Type Ranges if (recordType >= 0x00 && recordType <= 0xBF) { // Standard Range. 0x02 "System Event". (Spec declares 0x02. TODO: Monitor the range here) message.EventFormat = EventMessageFormat.SystemEvent; // Format Standard SEL record SelSupport.StandardSelFormat(ref message, messageData); message.EventMessage = ExtractSystemEventRecordMessage(message.RawSensorType, message.EventTypeCode, message.RawPayload); } else if ((recordType >= 0xC0) && (recordType <= 0xDF)) { // Time Stamped OEM. (override type to reduce string repetition in resource file) message.EventFormat = EventMessageFormat.OemTimeStamped; // Format "TimeStamped OEM" SEL record SelSupport.TimeStampedOEMSelFormat(ref message, messageData); message.EventMessage = ExtractOemTimestampedEventMessage(message.RawPayload); } else if ((recordType >= 0xE0) && (recordType <= 0xFF)) { // Non TimeStamped OEM. (override type to reduce string repetition in resource file) message.EventFormat = EventMessageFormat.OemNonTimeStamped; // Format "Non TimeStamped OEM" SEL record SelSupport.NonTimestampedOemSelFormat(ref message, messageData); message.EventMessage = ExtractOemNonTimestampedEventMessage(message.RawPayload); } // add message to the collection messageCollection.EventLog.Add(message); } } } return(messageCollection); }