示例#1
0
        public override bool ChecksumsMatch(IModbusMessage message, byte[] messageFrame)
        {
            ushort messageCrc    = BitConverter.ToUInt16(messageFrame, messageFrame.Length - 2);
            ushort calculatedCrc = BitConverter.ToUInt16(ModbusUtility.CalculateCrc(message.MessageFrame), 0);

            return(messageCrc == calculatedCrc);
        }
示例#2
0
        public void ReadResponseSlaveException()
        {
            var mock = new Mock <ModbusRtuTransport>(StreamResource)
            {
                CallBase = true
            };
            var transport = mock.Object;

            byte[] messageFrame = { 0x01, 0x81, 0x02 };
            byte[] crc          = ModbusUtility.CalculateCrc(messageFrame);

            mock.Setup(t => t.Read(ModbusRtuTransport.ResponseFrameStartLength))
            .Returns(Enumerable.Concat(messageFrame, new byte[] { crc[0] }).ToArray());

            mock.Setup(t => t.Read(1))
            .Returns(new byte[] { crc[1] });

            var response = transport.ReadResponse <ReadCoilsInputsResponse>();

            Assert.IsType <SlaveExceptionResponse>(response);

            var expectedResponse = new SlaveExceptionResponse(0x01, 0x81, 0x02);

            Assert.Equal(expectedResponse.MessageFrame, response.MessageFrame);

            mock.VerifyAll();
        }
示例#3
0
        internal override bool ChecksumsMatch(IModbusMessage message, byte[] messageFrame)
        {
            var messInt = BitConverter.ToUInt16(messageFrame, messageFrame.Length - 2);

            var frameInt = BitConverter.ToUInt16(ModbusUtility.CalculateCrc(message.MessageFrame), 0);

            return(messInt == frameInt);
        }
示例#4
0
        /// <summary>
        /// Sets the crc of the message.
        /// </summary>
        /// <param name="message"></param>
        public static void SetCrc(this byte[] message)
        {
            var messageFrame = message.Take(message.Length - 2).ToArray();

            var crc = ModbusUtility.CalculateCrc(messageFrame);

            message[message.Length - 2] = crc[0];
            message[message.Length - 1] = crc[1];
        }
示例#5
0
        internal override byte[] BuildMessageFrame(IModbusMessage message)
        {
            List <byte> messageBody = new List <byte>();

            messageBody.Add(message.SlaveAddress);
            messageBody.AddRange(message.ProtocolDataUnit);
            messageBody.AddRange(ModbusUtility.CalculateCrc(message.MessageFrame));

            return(messageBody.ToArray());
        }
示例#6
0
 public byte[] getCRC(byte[] arr)
 {
     byte[] crc      = ModbusUtility.CalculateCrc(arr);
     byte[] numArray = new byte[8];
     for (int index = 0; index < 8; ++index)
     {
         numArray[index] = index >= 6 ? crc[index - 6] : arr[index];
     }
     return(numArray);
 }
示例#7
0
        private bool ValidateCrc(byte[] buf)
        {
            var datalength = (int)(buf[2]);
            var databuf    = new byte[buf.Length - 2];

            Buffer.BlockCopy(buf, 0, databuf, 0, databuf.Length);
            var crc = ModbusUtility.CalculateCrc(databuf);

            return(crc[0] == buf[datalength + 3] && crc[1] == buf[datalength + 3 + 1]);
        }
示例#8
0
文件: Modbus.cs 项目: nxzzkj/lazyiot
        public byte[] BuildModbusReadBytes()
        {
            List <Byte> readBytes = new List <byte>();

            readBytes.Add((byte)DevAddress);
            readBytes.Add(Convert.ToByte(Code));
            readBytes.AddRange(BitConverter.GetBytes(StartRegister));
            readBytes.AddRange(BitConverter.GetBytes(RegisterNum));
            readBytes.AddRange(ModbusUtility.CalculateCrc(readBytes.ToArray()));//加入校验码
            return(readBytes.ToArray());
        }
示例#9
0
        public override byte[] BuildMessageFrame(IModbusMessage message)
        {
            byte[] pdu         = message.MessageFrame;
            byte[] crc         = ModbusUtility.CalculateCrc(message.MessageFrame);
            var    messageBody = new MemoryStream(pdu.Length + crc.Length);

            messageBody.Write(pdu, 0, pdu.Length);
            messageBody.Write(crc, 0, crc.Length);

            return(messageBody.ToArray());
        }
示例#10
0
        internal override byte[] BuildMessageFrame(IModbusMessage message)
        {
            var messageFrame = message.MessageFrame;
            var crc          = ModbusUtility.CalculateCrc(messageFrame);
            var messageBody  = new MemoryStream(messageFrame.Length + crc.Length);

            messageBody.Write(messageFrame, 0, messageFrame.Length);
            messageBody.Write(crc, 0, crc.Length);

            return(messageBody.ToArray());
        }
示例#11
0
        /// <summary>
        /// Determines whether the crc stored in the message matches the calculated crc.
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public static bool DoesCrcMatch(this byte[] message)
        {
            var messageFrame = message.Take(message.Length - 2).ToArray();

            //Calculate the CRC with the given set of bytes
            var calculatedCrc = BitConverter.ToUInt16(ModbusUtility.CalculateCrc(messageFrame), 0);

            //Get the crc that is stored in the message
            var messageCrc = message.GetCRC();

            //Determine if they match
            return(calculatedCrc == messageCrc);
        }
示例#12
0
        public Function12RequestRead(byte functionCode, ushort startAddress, ushort numOfPoints, byte devicenumber, byte moduleNumber) : base(devicenumber, functionCode)
        {
            List <byte> customBytes = new List <byte>();
            var         res         = 0xF0 | moduleNumber;

            customBytes.Add(Convert.ToByte(res));
            ReadHoldingInputRegistersRequest innerRequest = new ReadHoldingInputRegistersRequest(Modbus.ReadInputRegisters, devicenumber, startAddress, numOfPoints);

            byte[] crcforinnerRequest = ModbusUtility.CalculateCrc(innerRequest.MessageFrame);
            customBytes.AddRange(innerRequest.MessageFrame);
            customBytes.AddRange(crcforinnerRequest);


            MessageImpl.CustomBytesInRequest = customBytes.ToArray();
        }
示例#13
0
        private void IntPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            int byteRecieved = this.IntPort.BytesToRead;

            byte[] responseBytes = new byte[byteRecieved];
            if (responseBytes.Length == 0)
            {
                return;
            }
            this.IntPort.Read(responseBytes, 0, byteRecieved);
            this.intbusRecievedBuffer.AddRange(responseBytes);

            if (ModbusUtility.IsValidCrc(this.intbusRecievedBuffer))
            {
                cancelTimeoutToken.Cancel();
                this.timeoutTask.Wait();
                cancelTimeoutToken.Dispose();
                cancelTimeoutToken    = new CancellationTokenSource();
                this.timeoutTaskToken = cancelTimeoutToken.Token;

                IEnumerable <byte> expectedPreambule = this.currentDevice.CalculatePreambule();
                IEnumerable <byte> actualPreambule   = this.intbusRecievedBuffer.Take(expectedPreambule.Count());

                if (expectedPreambule.Zip(actualPreambule, (f, s) => new { f, s }).Any(p => p.f != p.s))
                {
                    this.SerialDataIntBUSResponse("Preambule ERROR");
                    return;
                }

                if (this.intbusRecievedBuffer.Skip(expectedPreambule.Count()).First() !=
                    this.currentDevice.ModbusAddress)
                {
                    this.SerialDataIntBUSResponse("ModbusAddress ERROR");
                    return;
                }


                var receivedMbFrame = this.intbusRecievedBuffer
                                      .Take(this.intbusRecievedBuffer.Count - 2)
                                      .Skip(expectedPreambule.Count());
                var crc = ModbusUtility.CalculateCrc(receivedMbFrame.ToArray());
                this.intbusRecievedBuffer = receivedMbFrame
                                            .ToList();
                this.intbusRecievedBuffer.AddRange(crc);

                this.SerialDataIntBUSResponse("");
            }
        }
示例#14
0
        public void UnicastMessage_PurgeReceiveBuffer()
        {
            var             mock           = new Mock <IStreamResource>(MockBehavior.Strict);
            IStreamResource serialResource = mock.Object;
            var             factory        = new ModbusFactory();
            var             transport      = new ModbusRtuTransport(serialResource, factory, NullModbusLogger.Instance);

            mock.Setup(s => s.DiscardInBuffer());
            mock.Setup(s => s.Write(It.IsAny <byte[]>(), 0, 0));

            serialResource.DiscardInBuffer();
            serialResource.Write(null, 0, 0);

            // mangled response
            mock.Setup(s => s.Read(It.Is <byte[]>(x => x.Length == 4), 0, 4)).Returns(4);

            serialResource.DiscardInBuffer();
            serialResource.Write(null, 0, 0);

            // normal response
            var response = new ReadCoilsInputsResponse(ModbusFunctionCodes.ReadCoils, 2, 1, new DiscreteCollection(true, false, true, false, false, false, false, false));

            // write request
            mock.Setup(s => s.Write(It.Is <byte[]>(x => x.Length == 8), 0, 8));

            // read header
            mock.Setup(s => s.Read(It.Is <byte[]>(x => x.Length == 4), 0, 4))
            .Returns((byte[] buf, int offset, int count) =>
            {
                Array.Copy(response.MessageFrame, 0, buf, 0, 4);
                return(4);
            });

            // read remainder
            mock.Setup(s => s.Read(It.Is <byte[]>(x => x.Length == 2), 0, 2))
            .Returns((byte[] buf, int offset, int count) =>
            {
                Array.Copy(ModbusUtility.CalculateCrc(response.MessageFrame), 0, buf, 0, 2);
                return(2);
            });

            var request = new ReadCoilsInputsRequest(ModbusFunctionCodes.ReadCoils, 2, 3, 4);
            ReadCoilsInputsResponse actualResponse = transport.UnicastMessage <ReadCoilsInputsResponse>(request);

            ModbusMessageFixture.AssertModbusMessagePropertiesAreEqual(response, actualResponse);
            mock.VerifyAll();
        }
        public void UnicastMessage_PurgeReceiveBuffer()
        {
            MockRepository        mocks          = new MockRepository();
            IStreamResource       serialResource = mocks.StrictMock <IStreamResource>();
            ModbusSerialTransport transport      = new ModbusRtuTransport(serialResource);

            serialResource.DiscardInBuffer();
            serialResource.Write(null, 0, 0);
            LastCall.IgnoreArguments();

            // mangled response
            Expect.Call(serialResource.Read(new byte[] { 0, 0, 0, 0 }, 0, 4)).Return(4);

            serialResource.DiscardInBuffer();
            serialResource.Write(null, 0, 0);
            LastCall.IgnoreArguments();

            // normal response
            ReadCoilsInputsResponse response = new ReadCoilsInputsResponse(Modbus.ReadCoils, 2, 1,
                                                                           new DiscreteCollection(true, false, true, false, false, false, false, false));

            // read header
            Expect.Call(serialResource.Read(new byte[] { 0, 0, 0, 0 }, 0, 4))
            .Do(((Func <byte[], int, int, int>) delegate(byte[] buf, int offset, int count)
            {
                Array.Copy(response.MessageFrame, 0, buf, 0, 4);
                return(4);
            }));

            // read remainder
            Expect.Call(serialResource.Read(new byte[] { 0, 0 }, 0, 2))
            .Do(((Func <byte[], int, int, int>) delegate(byte[] buf, int offset, int count)
            {
                Array.Copy(ModbusUtility.CalculateCrc(response.MessageFrame), 0, buf, 0, 2);
                return(2);
            }));

            mocks.ReplayAll();

            ReadCoilsInputsRequest request = new ReadCoilsInputsRequest(Modbus.ReadCoils, 2, 3, 4);

            transport.UnicastMessage <ReadCoilsInputsResponse>(request);

            mocks.VerifyAll();
        }
示例#16
0
        public Function12RequestWrite(byte functionCode, ushort startAddress, byte devicenumber, byte moduleNumber, ushort[] writeArray) : base(devicenumber, functionCode)
        {
            List <byte> customBytes = new List <byte>();
            var         res         = 0xF0 | moduleNumber;

            customBytes.Add(Convert.ToByte(res));

            WriteMultipleRegistersRequest innerRequest =
                new WriteMultipleRegistersRequest(devicenumber, startAddress, new RegisterCollection(writeArray));

            InnerReauest = innerRequest;
            byte[] crcforinnerRequest = ModbusUtility.CalculateCrc(innerRequest.MessageFrame);
            customBytes.AddRange(innerRequest.MessageFrame);
            customBytes.AddRange(crcforinnerRequest);


            MessageImpl.CustomBytesInRequest = customBytes.ToArray();
        }
        public void ReadResponseSlaveException()
        {
            MockRepository     mocks     = new MockRepository();
            ModbusRtuTransport transport = mocks.PartialMock <ModbusRtuTransport>(MockRepository.GenerateStub <IStreamResource>());

            byte[] messageFrame = { 0x01, 0x81, 0x02 };
            byte[] crc          = ModbusUtility.CalculateCrc(messageFrame);

            Expect.Call(transport.Read(ModbusRtuTransport.ResponseFrameStartLength))
            .Return(messageFrame.Concat(SequenceUtility.ToSequence(crc[0])).ToArray());

            Expect.Call(transport.Read(1))
            .Return(new byte[] { crc[1] });

            mocks.ReplayAll();

            Assert.IsTrue(transport.ReadResponse <ReadCoilsInputsResponse>() is SlaveExceptionResponse);

            mocks.VerifyAll();
        }
示例#18
0
 public void CalculateCrcNull()
 {
     ModbusUtility.CalculateCrc(null);
     Assert.Fail();
 }
示例#19
0
 public void CalculateCrcEmpty()
 {
     Assert.AreEqual(new byte[] { 255, 255 }, ModbusUtility.CalculateCrc(new byte[] { }));
 }
示例#20
0
 public void CalculateCrc2()
 {
     byte[] result = ModbusUtility.CalculateCrc(new byte[] { 2, 1, 5, 0 });
     Assert.AreEqual(new byte[] { 83, 12 }, result);
 }
示例#21
0
 public void CalculateCrc()
 {
     byte[] result = ModbusUtility.CalculateCrc(new byte[] { 1, 1 });
     Assert.AreEqual(new byte[] { 193, 224 }, result);
 }
示例#22
0
 internal override bool ChecksumsMatch(IModbusMessage message, byte[] messageFrame)
 {
     return(BitConverter.ToUInt16(messageFrame, messageFrame.Length - 2) ==
            BitConverter.ToUInt16(ModbusUtility.CalculateCrc(message.MessageFrame), 0));
 }
示例#23
0
        public void StartServer(int port)
        {
            if (_wrapper.StartService((ushort)port) == 0)
            {
                var exception = Marshal.AllocHGlobal(200);
                _wrapper.GetLastError(exception, 200);
                throw new Exception("启动DTU监听失败" + Marshal.PtrToStringAnsi(exception));
            }

            Logger.Enqueue("DTU服务启动");

            var dds = _dataStruct.CreateNewInstance();

            //读取线程
            #region 读取线程
            ThreadPool.QueueUserWorkItem(o =>
            {
                int rc = 0;
                while (IsRunning)
                {
                    rc = _wrapper.GetNextData(ref dds, 1);
                    if (rc != 0)
                    {
                        //var phoneNo = Encoding.Default.GetString(dds.m_phoneno);
                        var modId       = dds.Id;
                        var configModel = ConfigurationAdapter.GetConfigTable()[BitConverter.ToInt32(modId, 0).ToString()];
                        switch (configModel.ServerFunctionCode)
                        {
                        case 1:
                        case 2:
                            break;

                        case 4:
                            {
                                if (showLog)
                                {
                                    Logger.Enqueue("DTU收到数据dtuId:" + BitConverter.ToInt32(dds.Id, 0));
                                    Logger.Enqueue("DTU收到数据data_len:" + BitConverter.ToInt16(dds.DataLength, 0));
                                }
                                //判断站号
                                if (dds.DataBuff[0] != configModel.DTUDeviceId)
                                {
                                    Logger.Enqueue("DTU服务收到错误DEVICEID:" + dds.DataBuff[0]);
                                }
                                if (dds.DataBuff[1] != 4)
                                {
                                    Logger.Enqueue("DTU服务收到错误FunctionCode:" + dds.DataBuff[1]);
                                }


                                var realData = new byte[BitConverter.ToInt16(dds.DataLength, 0)];
                                Buffer.BlockCopy(dds.DataBuff, 0, realData, 0, realData.Length);
                                //验证CRC
                                if (!ValidateCrc(realData))
                                {
                                    Logger.Enqueue("DTU服务收到错误CRC:验证未通过");
                                }

                                //解析读协议
                                var length = dds.DataBuff[2];

                                if (showLog)
                                {
                                    Logger.Enqueue("协议数据包长度:" + length);
                                }
                                var strBuf = new StringBuilder();
                                for (var i = 3; i < length + 3; i++)
                                {
                                    if (showLog)
                                    {
                                        Logger.Enqueue("写入INPUT寄存器:" + (configModel.ServerAddressStart + i - 3) + "|" +
                                                       (dds.DataBuff[i]));
                                    }
                                    slaveDataStore.InputRegisters[configModel.ServerAddressStart + i - 3] =
                                        dds.DataBuff[i];
                                    strBuf.Append(dds.DataBuff[i].ToString());
                                }
                                File.AppendAllText(
                                    configModel.DTUId + "_" + DateTime.Now.Date.ToString("yyyyMMdd") + ".txt",
                                    "[" + DateTime.Now + "]" + strBuf.ToString() + "\r\n");
                            }
                            break;

                        case 3:
                            {
                                if (showLog)
                                {
                                    Logger.Enqueue("DTU收到数据dtuId:" + BitConverter.ToInt32(dds.Id, 0));
                                    Logger.Enqueue("DTU收到数据data_len:" + BitConverter.ToInt16(dds.DataLength, 0));
                                }
                                //判断站号
                                if (dds.DataBuff[0] != configModel.DTUDeviceId)
                                {
                                    Logger.Enqueue("DTU服务收到错误DEVICEID:" + dds.DataBuff[0]);
                                }
                                if (dds.DataBuff[1] != 3)
                                {
                                    Logger.Enqueue("DTU服务收到错误FunctionCode:" + dds.DataBuff[1]);
                                }
                                var realData = new byte[BitConverter.ToInt16(dds.DataLength, 0)];
                                Buffer.BlockCopy(dds.DataBuff, 0, realData, 0, realData.Length);
                                //验证CRC
                                if (!ValidateCrc(realData))
                                {
                                    Logger.Enqueue("DTU服务收到错误CRC:验证未通过");
                                }

                                //解析读协议
                                var length = dds.DataBuff[2];
                                if (showLog)
                                {
                                    Logger.Enqueue("协议数据包长度:" + length);
                                }
                                var strBuf = new StringBuilder();
                                for (var i = 3; i < length + 3; i++)
                                {
                                    if (showLog)
                                    {
                                        Logger.Enqueue("写入INPUT寄存器:" + (configModel.ServerAddressStart + i - 3) + "|" +
                                                       (dds.DataBuff[i]));
                                    }
                                    slaveDataStore.HoldingRegisters[configModel.ServerAddressStart + i - 3] =
                                        dds.DataBuff[i];
                                }
                                File.AppendAllText(
                                    configModel.DTUId + "_" + DateTime.Now.Date.ToString("yyyyMMdd") + ".txt",
                                    "[" + DateTime.Now + "]" + strBuf.ToString() + "\r\n");
                            } break;
                        }
                    }
                    Thread.Sleep(50);
                }
            });
            #endregion 读取线程

            //寻址线程
            #region 寻址线程
            ThreadPool.QueueUserWorkItem(o =>
            {
                while (IsRunning)
                {
                    lock (m_lock)
                    {
                        SiteList = new Dictionary <string, Hashtable>();
                        foreach (var siteinfo in SiteInfoList)
                        {
                            SiteList.Add(siteinfo["ID"].ToString(), siteinfo);
                        }
                    }

                    var configTable = ConfigurationAdapter.GetConfigTable();
                    foreach (var kv in configTable)
                    {
                        if (SiteList.ContainsKey(kv.Key))
                        {
                            var dataByte  = new byte[6];
                            dataByte[0]   = (byte)kv.Value.DTUDeviceId;
                            dataByte[1]   = (byte)kv.Value.DTUFunctionCode;
                            dataByte[2]   = (byte)(kv.Value.DTUAddressStart / 256);
                            dataByte[3]   = (byte)(kv.Value.DTUAddressStart % 256);
                            dataByte[4]   = (byte)(kv.Value.DTUAddressLength / 256);
                            dataByte[5]   = (byte)(kv.Value.DTUAddressLength % 256);
                            var crc       = ModbusUtility.CalculateCrc(dataByte);
                            var sendBytes = new byte[8];
                            Buffer.BlockCopy(dataByte, 0, sendBytes, 0, 6);
                            Buffer.BlockCopy(crc, 0, sendBytes, 6, 2);
                            var result = _wrapper.SendData(uint.Parse(kv.Value.DTUId), (ushort)sendBytes.Length, sendBytes);

                            if (showLog)
                            {
                                Logger.Enqueue("发送数据到" + kv.Value.DTUId + ":" + result.ToString());
                            }
                            if (result == 0)
                            {
                                try
                                {
                                    var strError = Marshal.AllocHGlobal(200);
                                    _wrapper.GetLastError(strError, 200);
                                    Logger.Enqueue(Marshal.PtrToStringAnsi(strError));
                                }
                                catch (Exception ex)
                                {
                                    Logger.Enqueue(ex.Message);
                                }
                            }
                            var str = new StringBuilder();
                            for (var i = 0; i < sendBytes.Length; i++)
                            {
                                str.AppendFormat(@"{0} ", sendBytes[i].ToString());
                            }
                            File.AppendAllText(
                                kv.Key + "_" + DateTime.Now.Date.ToString("yyyyMMdd") + "_Sent.txt",
                                "[" + DateTime.Now + "]" + str.ToString() + "\r\n");
                        }
                    }
                    Thread.Sleep(1000);
                }
            });
            #endregion

            //接收DTU线程
            #region 接收DTU连接线程
            ThreadPool.QueueUserWorkItem(o =>
            {
                while (IsRunning)
                {
                    uint rc = 0;
                    rc      = _wrapper.GetDtuCount();
                    if (rc != SiteOnline)
                    {
                        Logger.Enqueue("刷新DTU列表");
                        lock (m_lock)
                        {
                            SiteInfoList.Clear();
                            for (uint i = 0; i < rc; i++)
                            {
                                IInfoStruct dis = _infoStruct.CreateNewInstance();
                                if (_wrapper.GetDtuByPosition(i, ref dis) > 0)
                                {
                                    int id          = BitConverter.ToInt32(dis.Id, 0);
                                    string sim      = Encoding.Default.GetString(dis.Id, 0, dis.Id.Length);
                                    string ip       = StIPtoString(dis.DynamicIp);
                                    string sitename = string.Format("{0}:{1}", id, sim);
                                    SiteInfoList.Add(new Hashtable
                                    {
                                        { "SiteName", sitename },
                                        { "ID", id },
                                        { "SIM", sim },
                                        { "IP", ip },
                                        //{"ConnTime", UxToDateTime(dis.m_conn_time)},
                                        //{"LastTime", UxToDateTime(dis.m_refresh_time)},
                                    });
                                    Logger.Enqueue("id:" + id);
                                    Logger.Enqueue("sim:" + sim);
                                    Logger.Enqueue("ip:" + ip);
                                    Logger.Enqueue("sitename:" + sitename);
                                }
                            }
                        }
                    }
                    SiteOnline = rc;
                    Thread.Sleep(5000);
                }
            });
            #endregion
        }
示例#24
0
 public void CalculateCrcNull()
 {
     Assert.Throws <ArgumentNullException>(() => ModbusUtility.CalculateCrc(null));
 }