示例#1
0
        private void Deserialize(byte[] bytes)
        {
            var buffer = new DataBuffer(bytes);

            DeviceId = buffer.GetByte(0);
            Function = (FunctionCode)buffer.GetByte(1);

            byte[] crcBuff = buffer.GetBytes(buffer.Length - 3, 2);
            byte[] crcCalc = Checksum.CRC16(bytes, 0, bytes.Length - 2);

            if (crcBuff[0] != crcCalc[0] || crcBuff[1] != crcCalc[1])
            {
                throw new InvalidOperationException("Data not valid (CRC check failed).");
            }

            switch (Function)
            {
            case FunctionCode.ReadCoils:
            case FunctionCode.ReadDiscreteInputs:
            case FunctionCode.ReadHoldingRegisters:
            case FunctionCode.ReadInputRegisters:
                Address = buffer.GetUInt16(2);
                Count   = buffer.GetUInt16(4);
                break;

            case FunctionCode.WriteMultipleCoils:
            case FunctionCode.WriteMultipleRegisters:
                Address = buffer.GetUInt16(2);
                Count   = buffer.GetUInt16(4);
                Data    = new DataBuffer(buffer.GetBytes(6, buffer.Length - 8));
                break;

            case FunctionCode.WriteSingleCoil:
            case FunctionCode.WriteSingleRegister:
                Address = buffer.GetUInt16(2);
                Data    = new DataBuffer(buffer.GetBytes(4, buffer.Length - 6));
                break;

            case FunctionCode.EncapsulatedInterface:
                MEIType = (MEIType)buffer.GetByte(8);
                switch (MEIType)
                {
                case MEIType.CANOpenGeneralReference:
                    Data = new DataBuffer(buffer.Buffer.Skip(9).ToArray());
                    break;

                case MEIType.ReadDeviceInformation:
                    MEICategory = (DeviceIDCategory)buffer.GetByte(9);
                    MEIObject   = (DeviceIDObject)buffer.GetByte(10);
                    break;

                default:
                    throw new NotImplementedException($"Unknown MEI type: {MEIType}");
                }
                break;

            default:
                throw new NotImplementedException($"Unknown function code: {Function}");
            }
        }
示例#2
0
 internal bool TestCommunicationCircuit()
 {
     if (!Port.IsOpen)
     {
         return(false);
     }
     lock (synLocker)
     {
         byte[] data = new byte[8];
         data[0] = addr;
         data[1] = 0x08;
         data[2] = 0x00;
         data[3] = 0x00;
         data[4] = 0x17;
         data[5] = 0x70;
         byte[] crc = Checksum.CRC16(data, 6);
         data[6] = crc[0];
         data[7] = crc[1];
         if (InitTransArgs(8))
         {
             Port.Write(data, 0, 8);
             if (WaitForResponse(1000))
             {
                 byte[] recvData = new byte[8];
                 Port.Read(recvData, 0, 8);
                 return(recvData[1] == 0x08);
             }
         }
         return(false);
     }
 }
示例#3
0
 internal bool WriteOneRegisterValue(ushort address, ushort value)
 {
     if (!Port.IsOpen)
     {
         return(false);
     }
     lock (synLocker)
     {
         byte[] data = new byte[8];
         data[0] = addr;
         data[1] = 0x06;
         data[2] = (byte)(address >> 8 & 0xFF);
         data[3] = (byte)(address & 0xFF);
         data[4] = (byte)(value >> 8 & 0xFF);
         data[5] = (byte)(value & 0xFF);
         byte[] crc = Checksum.CRC16(data, 6);
         data[6] = crc[0];
         data[7] = crc[1];
         if (InitTransArgs(8))
         {
             Port.Write(data, 0, 8);
             if (WaitForResponse(2000))
             {
                 byte[] recvData = new byte[8];
                 Port.Read(recvData, 0, 8);
                 return(BitConverter.ToUInt64(recvData, 0) == BitConverter.ToUInt64(data, 0));
             }
         }
         return(false);
     }
 }
示例#4
0
 internal bool ReadRegisterValues(ushort address, out ushort[] value, int num = 1)
 {
     if (num > 20)
     {
         num = 20;
     }
     value = new ushort[num];
     if (!Port.IsOpen)
     {
         return(false);
     }
     lock (synLocker)
     {
         byte[] data = new byte[8];
         data[0] = addr;
         data[1] = 0x03;
         data[2] = (byte)(address >> 8 & 0xFF);
         data[3] = (byte)(address & 0xFF);
         data[4] = (byte)(num >> 8 & 0xFF);
         data[5] = (byte)(num & 0xFF);
         byte[] crc = Checksum.CRC16(data, 6);
         data[6]  = crc[0];
         data[7]  = crc[1];
         waitFlag = true;
         if (InitTransArgs(5 + num * 2))
         {
             Port.Write(data, 0, 8);
             if (WaitForResponse(500 * num))
             {
                 byte[] recvData = new byte[readBufferNum];
                 Port.Read(recvData, 0, readBufferNum);
                 if (recvData[2] == 2 * num)
                 {
                     for (int i = 0; i < num; i++)
                     {
                         value[i]   = recvData[3 + i * 2];
                         value[i] <<= 8;
                         value[i]  += recvData[4 + i * 2];
                     }
                     return(true);
                 }
             }
         }
         return(false);
     }
 }
示例#5
0
 internal bool WriteMultipleRegisterValues(ushort address, ushort[] value, int num)
 {
     if (!Port.IsOpen)
     {
         return(false);
     }
     if (value.Length < num)
     {
         num = value.Length;
     }
     lock (synLocker)
     {
         byte[] data = new byte[9 + num * 2];
         data[0] = addr;
         data[1] = 0x10;
         data[2] = (byte)(address >> 8 & 0xFF);
         data[3] = (byte)(address & 0xFF);
         data[4] = 0x00;
         data[5] = (byte)(num);
         data[6] = (byte)(data[5] * 2);
         for (int i = 0; i < data[6]; i += 2)
         {
             data[7 + i] = (byte)(value[i / 2] >> 8 & 0xFF);
             data[8 + i] = (byte)(value[i / 2] & 0xFF);
         }
         byte[] crc = Checksum.CRC16(data, 7 + num * 2);
         data[7 + num * 2] = crc[0];
         data[8 + num * 2] = crc[1];
         if (InitTransArgs(8))
         {
             Port.Write(data, 0, data.Length);
             if (WaitForResponse(2000))
             {
                 byte[] recvData = new byte[8];
                 Port.Read(recvData, 0, 8);
                 return(BitConverter.ToUInt32(data, 2) == BitConverter.ToUInt32(recvData, 2));
             }
         }
         return(false);
     }
 }
示例#6
0
        /// <summary>
        /// Serializes the request ready to send via serial.
        /// </summary>
        /// <returns></returns>
        public byte[] Serialize()
        {
            var buffer = new DataBuffer(2);

            buffer.SetByte(0, DeviceId);
            buffer.SetByte(1, (byte)Function);

            switch (Function)
            {
            case FunctionCode.ReadCoils:
            case FunctionCode.ReadDiscreteInputs:
            case FunctionCode.ReadHoldingRegisters:
            case FunctionCode.ReadInputRegisters:
                buffer.AddUInt16(Address);
                buffer.AddUInt16(Count);
                break;

            case FunctionCode.WriteMultipleCoils:
            case FunctionCode.WriteMultipleRegisters:
                buffer.AddUInt16(Address);
                buffer.AddUInt16(Count);
                if (Data?.Length > 0)
                {
                    buffer.AddBytes(Data.Buffer);
                }
                break;

            case FunctionCode.WriteSingleCoil:
            case FunctionCode.WriteSingleRegister:
                buffer.AddUInt16(Address);
                if (Data?.Length > 0)
                {
                    buffer.AddBytes(Data.Buffer);
                }
                break;

            case FunctionCode.EncapsulatedInterface:
                buffer.AddByte((byte)MEIType);
                switch (MEIType)
                {
                case MEIType.CANOpenGeneralReference:
                    if (Data?.Length > 0)
                    {
                        buffer.AddBytes(Data.Buffer);
                    }
                    break;

                case MEIType.ReadDeviceInformation:
                    buffer.AddByte((byte)MEICategory);
                    buffer.AddByte((byte)MEIObject);
                    break;

                default:
                    throw new NotImplementedException();
                }
                break;

            default:
                throw new NotImplementedException();
            }

            byte[] crc = Checksum.CRC16(buffer.Buffer);
            buffer.AddBytes(crc);

            return(buffer.Buffer);
        }
示例#7
0
        private void Deserialize(byte[] bytes)
        {
            // Response timed out => device not available
            if (bytes.All(b => b == 0))
            {
                IsTimeout = true;
                return;
            }

            var buffer = new DataBuffer(bytes);

            var crcBuff = buffer.GetBytes(buffer.Length - 2, 2);
            var crcCalc = Checksum.CRC16(bytes, 0, bytes.Length - 2);

            if (crcBuff[0] != crcCalc[0] || crcBuff[1] != crcCalc[1])
            {
                throw new InvalidOperationException("Data not valid (CRC check failed).");
            }

            DeviceId = buffer.GetByte(0);

            var fn = buffer.GetByte(1);

            if ((fn & Consts.ErrorMask) > 0)
            {
                Function  = (FunctionCode)(fn ^ Consts.ErrorMask);
                ErrorCode = (ErrorCode)buffer.GetByte(2);
            }
            else
            {
                Function = (FunctionCode)fn;

                switch (Function)
                {
                case FunctionCode.ReadCoils:
                case FunctionCode.ReadDiscreteInputs:
                case FunctionCode.ReadHoldingRegisters:
                case FunctionCode.ReadInputRegisters:
                    var len = buffer.GetByte(2);
                    if (buffer.Length != len + 3 + 2)                               // following bytes + 3 byte head + 2 byte CRC
                    {
                        throw new ArgumentException("Response incomplete");
                    }
                    Data = new DataBuffer(buffer.GetBytes(3, buffer.Length - 5));
                    break;

                case FunctionCode.WriteMultipleCoils:
                case FunctionCode.WriteMultipleRegisters:
                    Address = buffer.GetUInt16(2);
                    Count   = buffer.GetUInt16(4);
                    break;

                case FunctionCode.WriteSingleCoil:
                case FunctionCode.WriteSingleRegister:
                    Address = buffer.GetUInt16(2);
                    Data    = new DataBuffer(buffer.GetBytes(4, buffer.Length - 6));
                    break;

                case FunctionCode.EncapsulatedInterface:
                    MEIType = (MEIType)buffer.GetByte(2);
                    switch (MEIType)
                    {
                    case MEIType.CANOpenGeneralReference:
                        Data = new DataBuffer(buffer.Buffer.Skip(3).ToArray());
                        break;

                    case MEIType.ReadDeviceInformation:
                        MEICategory        = (DeviceIDCategory)buffer.GetByte(3);
                        ConformityLevel    = buffer.GetByte(4);
                        MoreRequestsNeeded = buffer.GetByte(5) > 0;
                        NextObjectId       = buffer.GetByte(6);
                        ObjectCount        = buffer.GetByte(7);
                        Data = new DataBuffer(buffer.Buffer.Skip(8).ToArray());
                        break;

                    default:
                        throw new NotImplementedException();
                    }
                    break;

                default:
                    throw new NotImplementedException();
                }
            }
        }
示例#8
0
        internal byte[] Serialize()
        {
            var buffer = new DataBuffer(2);

            buffer.SetByte(0, DeviceId);

            var fn = (byte)Function;

            if (IsError)
            {
                fn = (byte)(fn & Consts.ErrorMask);
                buffer.AddByte((byte)ErrorCode);
            }
            else
            {
                switch (Function)
                {
                case FunctionCode.ReadCoils:
                case FunctionCode.ReadDiscreteInputs:
                case FunctionCode.ReadHoldingRegisters:
                case FunctionCode.ReadInputRegisters:
                    buffer.AddByte((byte)Data.Length);
                    buffer.AddBytes(Data.Buffer);
                    break;

                case FunctionCode.WriteMultipleCoils:
                case FunctionCode.WriteMultipleRegisters:
                    buffer.AddUInt16(Address);
                    buffer.AddUInt16(Count);
                    break;

                case FunctionCode.WriteSingleCoil:
                case FunctionCode.WriteSingleRegister:
                    buffer.AddUInt16(Address);
                    buffer.AddBytes(Data.Buffer);
                    break;

                case FunctionCode.EncapsulatedInterface:
                    buffer.AddByte((byte)MEIType);
                    switch (MEIType)
                    {
                    case MEIType.CANOpenGeneralReference:
                        if (Data?.Length > 0)
                        {
                            buffer.AddBytes(Data.Buffer);
                        }
                        break;

                    case MEIType.ReadDeviceInformation:
                        buffer.AddByte((byte)MEICategory);
                        buffer.AddByte(ConformityLevel);
                        buffer.AddByte((byte)(MoreRequestsNeeded ? 0xFF : 0x00));
                        buffer.AddByte(NextObjectId);
                        buffer.AddByte(ObjectCount);
                        buffer.AddBytes(Data.Buffer);
                        break;

                    default:
                        throw new NotImplementedException();
                    }
                    break;

                default:
                    throw new NotImplementedException();
                }
            }

            buffer.SetByte(1, fn);

            var crc = Checksum.CRC16(buffer.Buffer);

            buffer.AddBytes(crc);

            return(buffer.Buffer);
        }