/// <summary>
        /// Initializes a new instance of the CpuPciConfigReadRequest class.
        /// </summary>
        internal CpuPciConfigReadRequest(byte cpuNumber, bool localspace,
                                         byte busNumber, byte deviceNumber, byte function, byte[] register, byte readLenght)
        {
            this.cpuNumber = (byte)(cpuNumber & 0x03);

            if (localspace)
            {
                this.cpuNumber = (byte)(cpuNumber | 0x40);
            }

            BitArray address = new BitArray(pciAddress);

            // register address byte 1 [0-7].
            IpmiSharedFunc.UpdateBitArray(ref address, 0, 7, register[0]);

            // register address byte 2 [8-11]
            IpmiSharedFunc.UpdateBitArray(ref address, 8, 11, register[1]);

            // function [12-14]
            IpmiSharedFunc.UpdateBitArray(ref address, 12, 14, function);

            // Device Number [15-19]
            IpmiSharedFunc.UpdateBitArray(ref address, 15, 19, deviceNumber);

            // Bus Number [20-27]
            IpmiSharedFunc.UpdateBitArray(ref address, 20, 27, busNumber);

            // copy all bits to byte array
            address.CopyTo(pciAddress, 0);

            this.readLenght = (byte)(readLenght & 0x03);
        }
            public ChassisFruWriteRequest(ushort offset, ushort length, byte[] dataToWrite)
            {
                byte lowOffset, highOffset, lowLength, highLength;

                IpmiSharedFunc.SplitWord(offset, out lowOffset, out highOffset);

                IpmiSharedFunc.SplitWord(length, out lowLength, out highLength);

                this.lowOffset   = lowOffset;
                this.highOffset  = highOffset;
                this.lowLength   = lowLength;
                this.highLength  = highLength;
                this.dataToWrite = dataToWrite;
            }
        /// <summary>
        /// Initializes a new instance of the CpuIaMsrReadRequest class.
        /// </summary>
        internal CpuIaMsrReadRequest(byte cpuNumber, byte threadId, byte[] msrAddress, byte readLenght)
        {
            this.cpuNumber = (byte)(cpuNumber & 0x03);

            this.threadId = threadId;

            BitArray address = new BitArray(pciAddress);

            // register address byte 1 [0-7].
            IpmiSharedFunc.UpdateBitArray(ref address, 0, 7, msrAddress[0]);

            // register address byte 2 [8-11]
            IpmiSharedFunc.UpdateBitArray(ref address, 8, 15, msrAddress[1]);

            // copy all bits to byte array
            address.CopyTo(pciAddress, 0);

            this.readLenght = (byte)(readLenght & 0x03);
        }
 /// <summary>
 /// Byte to Hex string representation
 /// </summary>
 public static string ByteToHexString(byte Bytes)
 {
     return(IpmiSharedFunc.ByteToHexString(Bytes));
 }
 /// <summary>
 /// Generates the text representation of an array of bytes
 /// </summary>
 /// <param name="Bytes"></param>
 /// <returns></returns>
 public static string ByteArrayToText(byte[] byteArray)
 {
     return(IpmiSharedFunc.ByteArrayToHexString(byteArray));
 }
        /// <summary>
        /// Convert the Node Manager 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="Node ManagerClient">Node ManagerClient instance.</param>
        /// <returns>byte array representing the Serial data to send.</returns>
        internal byte[] GetNodeManagerBytes(byte slaveId, byte rqSeq, bool trackResponse)
        {
            int dataLength = 0;

            #region dataLenght

            foreach (PropertyInfo propertyInfo in this.GetType().GetProperties())
            {
                NodeManagerMessageDataAttribute[] attributes2 =
                    (NodeManagerMessageDataAttribute[])propertyInfo.GetCustomAttributes(typeof(NodeManagerMessageDataAttribute), true);

                if (attributes2.Length > 0)
                {
                    if (propertyInfo.PropertyType == typeof(byte))
                    {
                        dataLength += 1;
                    }
                    else if (propertyInfo.PropertyType == typeof(ushort))
                    {
                        dataLength += 2;
                    }
                    else if (propertyInfo.PropertyType == typeof(short))
                    {
                        dataLength += 2;
                    }
                    else if (propertyInfo.PropertyType == typeof(int))
                    {
                        dataLength += 4;
                    }
                    else if (propertyInfo.PropertyType == typeof(uint))
                    {
                        dataLength += 4;
                    }
                    else if (propertyInfo.PropertyType == typeof(byte[]))
                    {
                        byte[] bytes = (byte[])propertyInfo.GetValue(this, null);
                        dataLength += bytes.Length;
                    }
                    else
                    {
                        Debug.Assert(false);
                    }
                }
            }

            #endregion

            // 07 bytes =   byte[0] slave Id, byte[1] netFnAndrqLun, byte[2] checksum1
            //              byte[3] rqAddr, byte[4] rqSeqAndrsLun, byte[5] command, byte[x] payload
            //              byte[6] checksum
            int messageLength = 7 + dataLength;

            byte[] messagedata = new byte[messageLength];

            // Encapsulate Node Manager message
            #region Message header

            messagedata[0] = slaveId;                                     // slave Id
            messagedata[1] = (byte)((byte)this.NodeManagerFunction << 2); // netFN
            messagedata[2] = 0x00;                                        // checksum zero'd for now.  Set after data added
            messagedata[3] = 0x20;                                        // for BMC when bridging to Intel ME.
            if (trackResponse)
            {
                messagedata[4] = (byte)(((byte)rqSeq << 2) | 0x02); // rqSeq/rqLun = 10.
            }
            else
            {
                messagedata[4] = (byte)((byte)rqSeq << 2);  // rqSeq/rqLun = 0x00.
            }
            messagedata[5] = (byte)this.NodeManagerCommand; // cmd

            #endregion

            // Node Manager message data
            #region Get message data.

            if (dataLength > 0)
            {
                data = new byte[dataLength];

                foreach (PropertyInfo propertyInfo in this.GetType().GetProperties())
                {
                    NodeManagerMessageDataAttribute[] attributes =
                        (NodeManagerMessageDataAttribute[])propertyInfo.GetCustomAttributes(typeof(NodeManagerMessageDataAttribute), true);

                    if (attributes.Length > 0)
                    {
                        if (propertyInfo.PropertyType == typeof(byte))
                        {
                            data[attributes[0].Offset] = (byte)propertyInfo.GetValue(this, new Object[0]);
                        }
                        else if (propertyInfo.PropertyType == typeof(ushort))
                        {
                            byte[] raw = BitConverter.GetBytes((ushort)propertyInfo.GetValue(this, new Object[0]));
                            Buffer.BlockCopy(raw, 0, data, attributes[0].Offset, 2);
                        }
                        else if (propertyInfo.PropertyType == typeof(short))
                        {
                            byte[] raw = BitConverter.GetBytes((short)propertyInfo.GetValue(this, new Object[0]));
                            Buffer.BlockCopy(raw, 0, data, attributes[0].Offset, 2);
                        }
                        else if (propertyInfo.PropertyType == typeof(uint))
                        {
                            byte[] raw = BitConverter.GetBytes((uint)propertyInfo.GetValue(this, new Object[0]));
                            Buffer.BlockCopy(raw, 0, data, attributes[0].Offset, raw.Length);
                        }
                        else if (propertyInfo.PropertyType == typeof(int))
                        {
                            byte[] raw = BitConverter.GetBytes((int)propertyInfo.GetValue(this, new Object[0]));
                            Buffer.BlockCopy(raw, 0, data, attributes[0].Offset, raw.Length);
                        }
                        else if (propertyInfo.PropertyType == typeof(byte[]))
                        {
                            byte[] raw = (byte[])propertyInfo.GetValue(this, new Object[0]);
                            Buffer.BlockCopy(raw, 0, data, attributes[0].Offset, raw.Length);
                        }
                        else
                        {
                            Debug.Assert(false);
                        }
                    }
                }

                // Add Node Manager message data
                // dataIndex + 6 offsets encapsulated Node Manager message
                Buffer.BlockCopy(data, 0, messagedata, 6, data.Length);
            }

            #endregion

            // Add checksum
            #region Message checksum

            // NodeManager message encapsulation format checksum 1
            // Set checksum 1: Byte 0 = rsAdd,
            // Byte 1 = netFn, Byte 2 = Checksum
            messagedata[2] = IpmiSharedFunc.TwoComplementChecksum(0, 2, messagedata);

            // Node Manager message encapsulation format checksum 2
            // checksum 2 begins after checksum 1.
            // checksum 2 calculated from rqAddr to end of data lenght.
            messagedata[(6 + dataLength)] = IpmiSharedFunc.TwoComplementChecksum(3, (6 + dataLength), messagedata);

            #endregion

            return(messagedata);
        }
        /// <summary>
        /// Returns a byte array with all bytes from a specific area of the fru: Chassis, Baseboard, Product
        /// </summary>
        private byte[] ReadFruAreaBytes(DeviceType deviceType, byte 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;
            ChassisFruReadRequest fruRequest =
                new ChassisFruReadRequest(loOffset, hiOffset, countToRead);

            ChassisFruReadResponse fruResponse = SendReceive <ChassisFruReadResponse>(deviceType, deviceId, (fruRequest));

            completionCode = fruResponse.CompletionCode;

            if (completionCode == (byte)CompletionCode.Success)
            {
                ushort dataSize = FruArea.AreaLength(fruResponse.DataReturned);
                totalDataRead = Math.Min(countToRead, dataSize);
                IpmiSharedFunc.AppendArrayToList(fruResponse.DataReturned, areaBytes, totalDataRead);
                offset += totalDataRead;
                int       pass      = 0;
                const int readLimit = 12;

                while (dataSize > totalDataRead && pass <= readLimit)
                {
                    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 ChassisFruReadRequest(loOffset, hiOffset, countToRead);
                    // send request for more data
                    fruResponse    = SendReceive <ChassisFruReadResponse>(deviceType, deviceId, (fruRequest));
                    totalDataRead += countToRead;
                    offset        += countToRead;

                    completionCode = fruResponse.CompletionCode;

                    if (completionCode == 0x00)
                    {
                        IpmiSharedFunc.AppendArrayToList(fruResponse.DataReturned, areaBytes, countToRead);
                    }
                    else
                    {
                        break;
                    }

                    pass++;
                }

                if (pass > 12)
                {
                    completionCode = (byte)CompletionCode.InvalidIterationCount;
                }
            }

            return(areaBytes.ToArray());
        }