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); }
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(); }
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); }
/// <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]; }
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()); }
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); }
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]); }
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()); }
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()); }
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()); }
/// <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); }
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(); }
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(""); } }
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(); }
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(); }
public void CalculateCrcNull() { ModbusUtility.CalculateCrc(null); Assert.Fail(); }
public void CalculateCrcEmpty() { Assert.AreEqual(new byte[] { 255, 255 }, ModbusUtility.CalculateCrc(new byte[] { })); }
public void CalculateCrc2() { byte[] result = ModbusUtility.CalculateCrc(new byte[] { 2, 1, 5, 0 }); Assert.AreEqual(new byte[] { 83, 12 }, result); }
public void CalculateCrc() { byte[] result = ModbusUtility.CalculateCrc(new byte[] { 1, 1 }); Assert.AreEqual(new byte[] { 193, 224 }, result); }
internal override bool ChecksumsMatch(IModbusMessage message, byte[] messageFrame) { return(BitConverter.ToUInt16(messageFrame, messageFrame.Length - 2) == BitConverter.ToUInt16(ModbusUtility.CalculateCrc(message.MessageFrame), 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 }
public void CalculateCrcNull() { Assert.Throws <ArgumentNullException>(() => ModbusUtility.CalculateCrc(null)); }