/// <summary> /// Convert the IPMI request meeting into a byte stream for transmission /// to the BMC over Serial. /// [Byte 0] [Byte 1] [Byte 2] [Byte 3] /// [StrChar] [rsAddr] [netFn] [chksum] /// [Byte 4] [Byte 5] [Byte 6] [Byte 7] [Byte 8] [Byte 9] /// [rqAddr] [rqSeq] [cmd] [payload] [cksum] [stop] /// </summary> /// <param name="IpmiRqSeq">Sequence id for message.</param> /// <returns>byte array representing the Serial data to send.</returns> internal byte[] GetBytes(IpmiTransport transport, byte IpmiRqSeq) { // payload lenght int dataLength = GetPayloadLenght(); // payload bytes byte[] payload = GetPayload(dataLength); // response message lenght int messageLength = dataLength; if (transport == IpmiTransport.Serial) { // Add 9 bytes for 7 byte header and start + stop byte // 09 bytes = byte[1] start, byte[2] rsAdd, byte[3] netFnAndrqLun, byte[4] checksum1 // byte[5] rqAddr, byte[6] rqSeqAndrsLun, byte[7] command, byte[x] payload // byte[8] checksum, byte[09] stop. messageLength += 9; } byte[] messagedata = new byte[messageLength]; if (transport == IpmiTransport.Serial) { // Step 1. Add Message Header. #region Message header messagedata[1] = 0x20; // rsAddr messagedata[2] = (byte)((byte)this.IpmiFunction << 2); // netFN messagedata[3] = 0x00; // checksum zero'd for now. Set after data. messagedata[4] = 0x81; // for serial can be 0x8F; messagedata[5] = (byte)((byte)IpmiRqSeq << 2); // rqSeq/rqLun messagedata[6] = (byte)this.IpmiCommand; // cmd #endregion // Step 2. Add payload Data. // Add ipmi message data // dataIndex + 7 offsets encapsulated ipmi message header & start charactor Buffer.BlockCopy(payload, 0, messagedata, 7, payload.Length); // Step 3. Add Message Checksum #region Message checksum // Set checksum 1: Byte 0 = Start Char, Byte 1 = rsAdd, // Byte 2 = netFn, Byte 3 = Checksum messagedata[3] = IpmiSharedFunc.TwoComplementChecksum(1, 3, messagedata); // Ipmi message encapsulation format checksum 2 // checksum 2 begins after checksum 1. // checksum 2 calculated from rqAddr to end of data lenght. messagedata[(7 + dataLength)] = IpmiSharedFunc.TwoComplementChecksum(4, (7 + dataLength), messagedata); #endregion } return(messagedata); }
/// <summary> /// Initialize Ipmi response messages and sets response properties. /// </summary> /// <param name="transport">Ipmi transport framing</param> /// <param name="message">Ipmi message payload</param> /// <param name="length">Ipmi message payload lenght</param> /// <param name="reqSeq">Ipmi request sequence number</param> internal void Initialize(IpmiTransport transport, byte[] message, int length, byte reqSeq) { // offset for data indexing int offset = 0; int dataLength = length; if (transport == IpmiTransport.Serial) { // index past serial frame byte [start byte] offset++; // ipmi encapsulation header byte rqAddr = message[offset++]; // rdAddr byte netFnrqLun = message[offset++]; // netFn byte checksum1 = message[offset++]; // checksum 1 byte rsAddr = message[offset++]; // rsAddr byte rqSeqrsLun = message[offset++]; // rqSeq/rqLun byte command = message[offset++]; // cmd this.completionCode = message[offset++]; // completion code // update sequence number once there's a receive match if (((byte)rqSeqrsLun >> 2) != reqSeq) { this.completionCode = 0xCF; } // Deduct 10 bytes for message header and frame bytes. // 10 bytes = byte[0] start, byte[1] reqAdd, byte[2] netFnAndrqLun, byte[3] checksum1 // byte[5] rsAddr, byte[6] rqSeqAndrsLun, byte[7] command, byte[8] completionCode // byte[9] checksum, byte[10] end dataLength = (length - 10); // checksum 2 byte checksum2 = message[(offset + dataLength)]; } else if (transport == IpmiTransport.Wmi) { // completion code this.completionCode = message[offset]; // index past Completion Code byte offset++; // remove 1 for the completion code byte. dataLength--; } // set response properties. SetProperties(message, offset, dataLength); }
/// <summary> /// Convert the IPMI request meeting into a byte stream for transmission /// to the BMC over Serial. /// [Byte 0] [Byte 1] [Byte 2] [Byte 3] /// [StrChar] [rsAddr] [netFn] [chksum] /// [Byte 4] [Byte 5] [Byte 6] [Byte 7] [Byte 8] [Byte 9] /// [rqAddr] [rqSeq] [cmd] [payload] [cksum] [stop] /// </summary> /// <param name="IpmiRqSeq">Sequence id for message.</param> /// <returns>byte array representing the Serial data to send.</returns> internal byte[] GetBytes(IpmiTransport transport, byte IpmiRqSeq) { // payload lenght int dataLength = GetPayloadLenght(); // payload bytes byte[] payload = GetPayload(dataLength); // response message lenght int messageLength = dataLength; if (transport == IpmiTransport.Serial) { // Add 9 bytes for 7 byte header and start + stop byte // 09 bytes = byte[1] start, byte[2] rsAdd, byte[3] netFnAndrqLun, byte[4] checksum1 // byte[5] rqAddr, byte[6] rqSeqAndrsLun, byte[7] command, byte[x] payload // byte[8] checksum, byte[09] stop. messageLength += 9; } byte[] messagedata = new byte[messageLength]; if (transport == IpmiTransport.Serial) { // Step 1. Add Message Header. #region Message header messagedata[1] = 0x20; // rsAddr messagedata[2] = (byte)((byte)this.IpmiFunction << 2); // netFN messagedata[3] = 0x00; // checksum zero'd for now. Set after data. messagedata[4] = 0x81; // for serial can be 0x8F; messagedata[5] = (byte)((byte)IpmiRqSeq << 2); // rqSeq/rqLun messagedata[6] = (byte)this.IpmiCommand; // cmd #endregion // Step 2. Add payload Data. // Add ipmi message data // dataIndex + 7 offsets encapsulated ipmi message header & start charactor Buffer.BlockCopy(payload, 0, messagedata, 7, payload.Length); // Step 3. Add Message Checksum #region Message checksum // Set checksum 1: Byte 0 = Start Char, Byte 1 = rsAdd, // Byte 2 = netFn, Byte 3 = Checksum messagedata[3] = IpmiSharedFunc.TwoComplementChecksum(1, 3, messagedata); // Ipmi message encapsulation format checksum 2 // checksum 2 begins after checksum 1. // checksum 2 calculated from rqAddr to end of data lenght. messagedata[(7 + dataLength)] = IpmiSharedFunc.TwoComplementChecksum(4, (7 + dataLength), messagedata); #endregion } return messagedata; }
/// <summary> /// Initialize Ipmi response messages and sets response properties. /// </summary> /// <param name="transport">Ipmi transport framing</param> /// <param name="message">Ipmi message payload</param> /// <param name="length">Ipmi message payload lenght</param> /// <param name="reqSeq">Ipmi request sequence number</param> internal void Initialize(IpmiTransport transport, byte[] message, int length, byte reqSeq) { // offset for data indexing int offset = 0; int dataLength = length; if (transport == IpmiTransport.Serial) { // index past serial frame byte [start byte] offset++; // ipmi encapsulation header byte rqAddr = message[offset++]; // rdAddr byte netFnrqLun = message[offset++]; // netFn byte checksum1 = message[offset++]; // checksum 1 byte rsAddr = message[offset++]; // rsAddr byte rqSeqrsLun = message[offset++]; // rqSeq/rqLun byte command = message[offset++]; // cmd this.completionCode = message[offset++]; // completion code // update sequence number once there's a receive match if (((byte)rqSeqrsLun >> 2) != reqSeq) this.completionCode = 0xCF; // Deduct 10 bytes for message header and frame bytes. // 10 bytes = byte[0] start, byte[1] reqAdd, byte[2] netFnAndrqLun, byte[3] checksum1 // byte[5] rsAddr, byte[6] rqSeqAndrsLun, byte[7] command, byte[8] completionCode // byte[9] checksum, byte[10] end dataLength = (length - 10); // checksum 2 byte checksum2 = message[(offset + dataLength)]; } else if (transport == IpmiTransport.Wmi) { // completion code this.completionCode = message[offset]; // index past Completion Code byte offset++; // remove 1 for the completion code byte. dataLength--; } // set response properties. SetProperties(message, offset, dataLength); }