using Edge.Core.Parser.BinaryParser.Attributes; using Edge.Core.Parser.BinaryParser.MessageEntity; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace HengShan_Pump_TQC_IFSF.MessageEntity { public enum MessageType { IFSF_MESSAGE_TYPE_READ = 0x00, IFSF_MESSAGE_TYPE_ANSWER = 0x20, IFSF_MESSAGE_TYPE_WRITE = 0x40, /// /// message type is an event, and need Ack. /// IFSF_MESSAGE_TYPE_UNSOLICITED_ACK = 0x60, IFSF_MESSAGE_TYPE_UNSOLICITED_WITHOUT_ACK = 0x80, IFSF_MESSAGE_TYPE_ACK = 0xE0 } public enum MessageCode { IFSF_MESSAGE_CODE_APPLICATION = 0, IFSF_MESSAGE_CODE_HEARTBEAT = 1, IFSF_MESSAGE_CODE_COMMUNICATION = 2 } public enum DatabaseAddress { IFSF_DB_ADDRESS_COMMUNICATION = 0x00, IFSF_DB_ADDRESS_CALCULATOR = 0x01, IFSF_DB_ADDRESS_FP_ID = (0x20 + 1), IFSF_DB_ADDRESS_LN_ID = 0x10, IFSF_DB_ADDRESS_PR_ID = 0x40, IFSF_DB_ADDRESS_PR_DAT = 0x61, IFSF_DB_ADDRESS_TR_DAT = 0x21, IFSF_DB_ADDRESS_ERROR_DAT = 0x41, } public abstract class IfsfMessageBase : MessageTemplateBase { //private byte messageToken; //private MessageType messageType; public IfsfMessageBase() { } [Format(1, EncodingType.BIN, -9990)] [Range(0, 255, "Originator subnet must range in 0 to 255, but actual is: {0}")] public byte OriginatorSubnet { get; set; } [Format(1, EncodingType.BIN, -9980)] [Range(0, 127, "Originator node must range in 0 to 127, but actual is: {0}")] public byte OriginatorNode { get; set; } [Format(1, EncodingType.BIN, -9970)] public MessageCode MessageCode { get; set; } } public class IfsfMessage : IfsfMessageBase { public IfsfMessage() { } public IfsfMessage(byte msgToken, MessageType msgType) { this.MessageToken = msgToken; this.MessageType = msgType; } [Format(1, EncodingType.BIN, -9999)] [Range(0, 255, "Recipient subnet must range in 1 to 255")] public byte RecipientSubnet { get; set; } [Format(1, EncodingType.BIN, -9995)] [Range(0, 127, "Recipient node must range in 1 to 127, but now is {0}")] public byte RecipientNode { get; set; } //[Format(1, EncodingType.BIN, -9960)] //public byte BlockNumber => 0x80; /// /// 000xxxxx (bit map) /// 000 indicates the message type is READ /// xxxxx is the token created by the originator of the message /// 010xxxxx /// 010 indicates message type is WRITE /// xxxxx is the token /// 111xxxxx /// 111 indicates type ACKNOWLEDGE /// xxxxx is the token /// [Format(1, EncodingType.BIN, -9950)] public byte RawMessageTokenAndStatus { get; protected set; } public byte MessageToken { get { return (byte)(this.RawMessageTokenAndStatus & 0x1F); } set { if (value > 0x1F) throw new ArgumentOutOfRangeException("message Token max value is 0x1F"); //E0 = 1110 0000 this.RawMessageTokenAndStatus = (byte)((this.RawMessageTokenAndStatus & 0xE0) + value); } } public MessageType MessageType { get { return (MessageType)(this.RawMessageTokenAndStatus & 0xE0); } set { //1F = 0001 1111 this.RawMessageTokenAndStatus = (byte)((this.RawMessageTokenAndStatus & 0x1F) + ((byte)value)); } } public byte[] DatabaseId { get { var dbLen = this.RawDatabaseData[0]; return this.RawDatabaseData.Skip(1).Take(dbLen).ToArray(); } set { var dbLen = value.Length; this.RawDatabaseData = new List(); this.RawDatabaseData.Add((byte)dbLen); this.RawDatabaseData.AddRange(value); } } [Format(2, EncodingType.BIN, -9940)] public int MessageLength { get; protected set; } /// /// database address len + databaseId + [dataId + dataLen + dataElement] /// [EnumerableFormat("MessageLength", -9920)] public List RawDatabaseData { get; set; } public override string ToLogString() { return this.GetType().Name + " " + base.ToLogString() + " MsgType: " + this.MessageType + ", MsgToken: " + this.MessageToken; } } }