|
|
using System; using System.Collections.Generic;
namespace Mirle.Component.MPLC.MCProtocol { /// <summary>
/// Frame3E
/// </summary>
public class Frame3E { /// <summary>
/// 建構式
/// </summary>
public Frame3E() { _networkNo = 0; _stationNo = 0; } /// <summary>
/// 建構式
/// </summary>
/// <param name="networkNo">網路編號</param>
/// <param name="stationNo">站點編號</param>
public Frame3E(int networkNo, int stationNo) { _networkNo = (byte)networkNo; _stationNo = (byte)stationNo; } /// <summary>
/// 完成碼
/// </summary>
private struct CompleteCode { /// <summary>
/// 沒有資料
/// </summary>
public const int NoData = 0xF000; /// <summary>
/// 有效資料
/// </summary>
public const int InvalidData = 0xF001; } /// <summary>
///
/// </summary>
private const byte _PCNo = 0xff; /// <summary>
///
/// </summary>
private const byte _IONo_L = 0xff; //0x03ff
/// <summary>
///
/// </summary>
private const byte _IONo_H = 0x03; //0x03ff
/// <summary>
///
/// </summary>
private const byte _CPUTimer_L = 0x10; //0x0010
/// <summary>
///
/// </summary>
private const byte _CPUTimer_H = 0x00; /// <summary>
///
/// </summary>
private const int _receiceDataMinimumBytes = 11; /// <summary>
///
/// </summary>
private readonly byte _networkNo = 0x00; /// <summary>
///
/// </summary>
private readonly byte _stationNo = 0x00; /// <summary>
///
/// </summary>
public readonly int MaximumWords = 960; /// <summary>
///
/// </summary>
/// <param name="mainCmd"></param>
/// <param name="subCmd"></param>
/// <param name="address"></param>
/// <param name="deviceCode"></param>
/// <param name="size"></param>
/// <param name="data"></param>
/// <returns></returns>
private byte[] CreateFrame(int mainCmd, int subCmd, int address, byte deviceCode, int size, IReadOnlyCollection<byte> data) { int dataLength = 12 + data.Count; var frame = new List<byte>() { 0x50, 0x00, //3E Frame
_networkNo, _PCNo, _IONo_L, _IONo_H, _stationNo, (byte)(dataLength % 256), (byte)(dataLength / 256), _CPUTimer_L , _CPUTimer_H, (byte)mainCmd, (byte)(mainCmd >> 8), (byte)subCmd, (byte)(subCmd >> 8), (byte)address, (byte)(address >> 8), (byte)(address >> 16), deviceCode, (byte)size, (byte)(size >> 8), }; frame.AddRange(data); return frame.ToArray(); } /// <summary>
///
/// </summary>
/// <param name="device"></param>
/// <param name="length"></param>
/// <returns></returns>
public byte[] CreateReadWordsFrame(MCDevice device, int length) { if (device == null && length < 1) { return null; } if (length > MaximumWords) { length = MaximumWords; } int mainCmd = 0x0401; int subCmd = 0x0000; int address = device.Address; byte deviceCode = device.BinaryDeviceCode; int size = length; return CreateFrame(mainCmd, subCmd, address, deviceCode, size, new List<byte>()); } /// <summary>
///
/// </summary>
/// <param name="device"></param>
/// <param name="data"></param>
/// <returns></returns>
public byte[] CreateWriteWordsFrame(MCDevice device, int[] data) { if (device == null && data == null) { return null; } int mainCmd = 0x1401; int subCmd = 0x0000; int address = device.Address; byte deviceCode = device.BinaryDeviceCode; int size = Math.Min(data.Length, MaximumWords); var byteData = new List<byte>(); for (int i = 0; i < Math.Min(data.Length, MaximumWords); i++) { byteData.Add((byte)data[i]); byteData.Add((byte)(data[i] >> 8)); } return CreateFrame(mainCmd, subCmd, address, deviceCode, size, byteData); } /// <summary>
///
/// </summary>
/// <param name="device"></param>
/// <returns></returns>
public byte[] CreateReadBitFrame(MCDevice device) { if (device == null) { return null; } int mainCmd = 0x0401; int subCmd = 0x0001; int address = device.Address; byte deviceCode = device.BinaryDeviceCode; int size = 1; return CreateFrame(mainCmd, subCmd, address, deviceCode, size, new List<byte>()); } /// <summary>
///
/// </summary>
/// <param name="device"></param>
/// <param name="isOn"></param>
/// <returns></returns>
public byte[] CreateWriteBitFrame(MCDevice device, bool isOn) { if (device == null) { return null; } int mainCmd = 0x1401; int subCmd = 0x0001; int address = device.Address; byte deviceCode = device.BinaryDeviceCode; int size = 1; var byteData = new List<byte>(); byteData.Add((byte)(isOn ? 0x10 : 0x00)); return CreateFrame(mainCmd, subCmd, address, deviceCode, size, byteData); } /// <summary>
///
/// </summary>
/// <param name="receiveData"></param>
/// <param name="value"></param>
/// <returns></returns>
public int ResolveReadBitReturnFrame(byte[] receiveData, out bool value) { if (receiveData == null || receiveData.Length < _receiceDataMinimumBytes) { value = false; return CompleteCode.NoData; } ushort dataBytesLength = BitConverter.ToUInt16(receiveData, 7); //+ CompleteCode 2Bytes
ushort completeCode = BitConverter.ToUInt16(receiveData, 9); if (receiveData.Length != 9 + dataBytesLength) { value = false; return CompleteCode.InvalidData; } value = receiveData[11] == 0x10; return completeCode; } /// <summary>
///
/// </summary>
/// <param name="receiveData"></param>
/// <returns></returns>
public int ResolveWriteBitReturnFrame(byte[] receiveData) { if (receiveData == null || receiveData.Length < _receiceDataMinimumBytes) { return CompleteCode.NoData; } ushort dataBytesLength = BitConverter.ToUInt16(receiveData, 7); //+ CompleteCode 2Bytes
ushort completeCode = BitConverter.ToUInt16(receiveData, 9); if (receiveData.Length != 9 + dataBytesLength) { return CompleteCode.InvalidData; } return completeCode; } /// <summary>
///
/// </summary>
/// <param name="receiveData"></param>
/// <param name="data"></param>
/// <returns></returns>
public int ResolveReadWordsReturnFrame(byte[] receiveData, out int[] data) { if (receiveData == null || receiveData.Length < _receiceDataMinimumBytes) { data = null; return CompleteCode.NoData; } ushort dataBytesLength = BitConverter.ToUInt16(receiveData, 7); //+ CompleteCode 2Bytes
ushort completeCode = BitConverter.ToUInt16(receiveData, 9); if (receiveData.Length != 9 + dataBytesLength) { data = null; return CompleteCode.InvalidData; } data = new int[(dataBytesLength - 2) / 2]; for (int i = 0; i < data.Length; i++) { data[i] = BitConverter.ToUInt16(receiveData, _receiceDataMinimumBytes + i * 2); } return completeCode; } /// <summary>
///
/// </summary>
/// <param name="receiveData"></param>
/// <returns></returns>
public int ResolveWriteWordsReturnFrame(byte[] receiveData) { if (receiveData == null || receiveData.Length < _receiceDataMinimumBytes) { return CompleteCode.NoData; } ushort dataBytesLength = BitConverter.ToUInt16(receiveData, 7); //+ CompleteCode 2Bytes
ushort completeCode = BitConverter.ToUInt16(receiveData, 9); if (receiveData.Length != 9 + dataBytesLength) { return CompleteCode.InvalidData; } return completeCode; } } }
|