/// <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);
        }