|
@@ -0,0 +1,192 @@
|
|
|
+using MECF.Framework.Common.Net;
|
|
|
+using MECF.Framework.Simulator.Core.Driver;
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+
|
|
|
+namespace CyberX8_Simulator.Devices
|
|
|
+{
|
|
|
+ public class FestoSocketSimulator : SocketDeviceSimulator
|
|
|
+ {
|
|
|
+
|
|
|
+ private const ushort MODULE_0_OUTPUT_DATA_ADDRESS = 0x9C42;
|
|
|
+ private const ushort MODULE_1_OUTPUT_DATA_ADDRESS = 0x9C43;
|
|
|
+ private const ushort MODULE_2_OUTPUT_DATA_ADDRESS = 0x9C44;
|
|
|
+ private const ushort MODULE_3_OUTPUT_DATA_ADDRESS = 0x9C45;
|
|
|
+
|
|
|
+
|
|
|
+ private const ushort MODULE_0_ECHO_OUTPUT_DATA_ADDRESS = 0xB151;
|
|
|
+ private const ushort MODULE_1_ECHO_OUTPUT_DATA_ADDRESS = 0xB153;
|
|
|
+ private const ushort MODULE_2_ECHO_OUTPUT_DATA_ADDRESS = 0xB155;
|
|
|
+ private const ushort MODULE_3_ECHO_OUTPUT_DATA_ADDRESS = 0xB157;
|
|
|
+
|
|
|
+ private IByteTransform byteTransform = new BigEndianByteTransformBase();
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ Dictionary<int, short> _festoOutputDataDic = new Dictionary<int, short>();
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public FestoSocketSimulator(int port) : base(port)
|
|
|
+ {
|
|
|
+ _festoOutputDataDic[0] = 0x00;
|
|
|
+ _festoOutputDataDic[1] = 0x00;
|
|
|
+ _festoOutputDataDic[2] = 0x00;
|
|
|
+ _festoOutputDataDic[3] = 0x00;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ protected override void ProcessUnsplitMessage(byte[] data)
|
|
|
+ {
|
|
|
+ short flag = byteTransform.TransInt16(data, 0);
|
|
|
+ byte channel = data[6];
|
|
|
+ byte command = data[7];
|
|
|
+ if (command == 0x03)
|
|
|
+ {
|
|
|
+ ushort startAddress = byteTransform.TransUInt16(data, 8);
|
|
|
+ short registerCount = byteTransform.TransInt16(data, 10);
|
|
|
+
|
|
|
+ byte[] bytes = new byte[2 * registerCount];
|
|
|
+ switch (startAddress)
|
|
|
+ {
|
|
|
+ case MODULE_0_OUTPUT_DATA_ADDRESS:
|
|
|
+ for(int i = 0; i < registerCount; i++)
|
|
|
+ {
|
|
|
+ Array.Copy(byteTransform.GetBytes(_festoOutputDataDic[0]), 0, bytes, i*2, 2);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case MODULE_1_OUTPUT_DATA_ADDRESS:
|
|
|
+ for (int i = 0; i < registerCount; i++)
|
|
|
+ {
|
|
|
+ Array.Copy(byteTransform.GetBytes(_festoOutputDataDic[1]), 0, bytes, i*2, 2);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case MODULE_2_OUTPUT_DATA_ADDRESS:
|
|
|
+ Array.Copy(byteTransform.GetBytes(_festoOutputDataDic[2]), 0, bytes, 0, 2);
|
|
|
+ break;
|
|
|
+ case MODULE_3_OUTPUT_DATA_ADDRESS:
|
|
|
+ Array.Copy(byteTransform.GetBytes(_festoOutputDataDic[3]), 0, bytes, 0, 2);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ OnWriteMessage(CreateReadResponse(flag, channel, command, registerCount, bytes));
|
|
|
+ }
|
|
|
+ else if(command == 0x06)
|
|
|
+ {
|
|
|
+ ushort startAddress = byteTransform.TransUInt16(data, 8);
|
|
|
+ short value = byteTransform.TransInt16(data, 10);
|
|
|
+ switch (startAddress)
|
|
|
+ {
|
|
|
+ case MODULE_0_ECHO_OUTPUT_DATA_ADDRESS:
|
|
|
+ _festoOutputDataDic[0] = value;
|
|
|
+ break;
|
|
|
+ case MODULE_1_ECHO_OUTPUT_DATA_ADDRESS:
|
|
|
+ _festoOutputDataDic[1] = value;
|
|
|
+ break;
|
|
|
+ case MODULE_2_ECHO_OUTPUT_DATA_ADDRESS:
|
|
|
+ _festoOutputDataDic[2] = value;
|
|
|
+ break;
|
|
|
+ case MODULE_3_ECHO_OUTPUT_DATA_ADDRESS:
|
|
|
+ _festoOutputDataDic[3] = value;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ OnWriteMessage(CreateWriteResponse(flag, channel, command, startAddress, value));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ OnWriteMessage(CreateError(flag, channel, command, 0x84));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ private byte[] CreateReadResponse(short flag, byte channel, byte command, short registerCount, byte[] values)
|
|
|
+ {
|
|
|
+ byte[] bytes = new byte[6 + 3 + values.Length];
|
|
|
+ Array.Copy(byteTransform.GetBytes(flag), 0, bytes, 0, 2);
|
|
|
+ bytes[2] = 0x00;
|
|
|
+ bytes[3] = 0x00;
|
|
|
+ short dataLength = (short)(3 + values.Length);
|
|
|
+ Array.Copy(byteTransform.GetBytes(dataLength), 0, bytes, 4, 2);
|
|
|
+ bytes[6] = channel;
|
|
|
+ bytes[7] = command;
|
|
|
+ bytes[8] = (byte)(2 * registerCount);
|
|
|
+ Array.Copy(values, 0, bytes, 9, values.Length);
|
|
|
+ return bytes;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ private byte[] CreateWriteResponse(short flag, byte channel, byte command, ushort startAddress, short value)
|
|
|
+ {
|
|
|
+ byte[] bytes = new byte[12];
|
|
|
+ Array.Copy(byteTransform.GetBytes(flag), 0, bytes, 0, 2);
|
|
|
+ bytes[2] = 0x00;
|
|
|
+ bytes[3] = 0x00;
|
|
|
+ bytes[4] = 0x00;
|
|
|
+ bytes[5] = 0x06;
|
|
|
+ bytes[6] = channel;
|
|
|
+ bytes[7] = command;
|
|
|
+ byte[] addressByt = byteTransform.GetBytes(startAddress);
|
|
|
+ Array.Copy(addressByt, 0, bytes, 8, 2);
|
|
|
+ byte[] valueByt = byteTransform.GetBytes(value);
|
|
|
+ Array.Copy(valueByt, 0, bytes, 10, 2);
|
|
|
+ return bytes;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ private byte[] CreateMultiWriteResponse(short flag, byte channel, byte command, short startAddress, short count)
|
|
|
+ {
|
|
|
+ byte[] byt = new byte[1];
|
|
|
+ return byt;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ private byte[] CreateError(short flag, byte channel, byte command, byte error)
|
|
|
+ {
|
|
|
+ byte[] bytes = new byte[9];
|
|
|
+ Array.Copy(byteTransform.GetBytes(flag), 0, bytes, 0, 2);
|
|
|
+ bytes[2] = 0x00;
|
|
|
+ bytes[3] = 0x00;
|
|
|
+ bytes[4] = 0x00;
|
|
|
+ bytes[5] = 0x03;
|
|
|
+ bytes[6] = channel;
|
|
|
+ bytes[7] = (byte)(command | 0x80);
|
|
|
+ bytes[8] = error;
|
|
|
+ return bytes;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+}
|