using JiShe.CollectBus.Common.Extensions; using JiShe.CollectBus.IotSystems.Protocols; using JiShe.CollectBus.Protocol.Contracts.Interfaces; using JiShe.CollectBus.Protocol.Contracts.Models; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using TouchSocket.Sockets; using Volo.Abp.Domain.Repositories; namespace JiShe.CollectBus.Protocol.Contracts.Abstracts { public abstract class ProtocolPlugin:IProtocolPlugin { //头部字节长度 public const int hearderLen = 6; public const int tPLen = 6; public const string errorData = "EE"; private readonly ILogger _logger; private readonly IRepository _protocolInfoRepository; public ProtocolPlugin(IServiceProvider serviceProvider, ILogger logger) { _logger = logger; _protocolInfoRepository = serviceProvider.GetRequiredService>(); } public abstract ProtocolInfo Info { get; } public virtual async Task GetAsync() => await Task.FromResult(Info); public virtual async Task AddAsync() { if (Info == null) { throw new ArgumentNullException(nameof(Info)); } await _protocolInfoRepository.DeleteDirectAsync(a => a.Name == Info.Name); await _protocolInfoRepository.InsertAsync(Info); //await _protocolInfoCache.Get() } public abstract Task AnalyzeAsync(ITcpSessionClient client, string messageReceived, Action? receivedAction = null) where T :class; /// /// 解析376.1帧 /// /// /// public virtual TB3761? Analysis3761(string messageReceived) { try { var hexStringList = messageReceived.StringToPairs(); // 初步校验 if (hexStringList.Count < 6 || hexStringList.FirstOrDefault() != "68" || hexStringList.Skip(5).Take(1).FirstOrDefault() != "68" || hexStringList.Count < 18 || hexStringList.LastOrDefault() != "16") { _logger.LogError($"解析Analysis3761校验不通过,报文:{messageReceived}"); } else { TB3761 tB3761 = new TB3761 { BaseHexMessage = new BaseHexMessage { HexMessageString = messageReceived, HexMessageList = hexStringList }, C = Analysis_C(hexStringList), A = Analysis_A(hexStringList), AFN_FC = Analysis_AFN_FC(hexStringList), SEQ = Analysis_SEQ(hexStringList), UnitData = Analysis_UnitData(hexStringList), DA = Analysis_DA(hexStringList), DT = Analysis_DT(hexStringList) }; return tB3761; } } catch (Exception ex) { _logger.LogError($"解析Analysis3761错误,报文:{messageReceived},异常:{ex.Message}"); } return null; } /// /// 控制域C解析 /// /// public virtual C? Analysis_C(List hexStringList) { try { if (hexStringList.Count > 6) { BaseHexMessage baseHexMessage = new BaseHexMessage { HexMessageList = hexStringList.GetRange(6, 1) // 控制域 1字节 }; baseHexMessage.HexMessageString = string.Join("", baseHexMessage.HexMessageList); if (baseHexMessage.HexMessageList.Count == 0) return null; string binStr = baseHexMessage.HexMessageString.HexTo4BinZero(); C c = new C { BaseHexMessage = baseHexMessage, FC = binStr.Substring(binStr.Length - 4, 4).BinToDec(), FCV = binStr.Substring(3, 1).BinToDec(), FCB = binStr.Substring(2, 1).BinToDec(), PRM = binStr.Substring(1, 1).BinToDec(), DIR = binStr.Substring(0, 1).BinToDec() }; return c; } } catch (Exception ex) { _logger.LogError($"解析Analysis_C错误,报文:{string.Join("", hexStringList)},异常:{ex.Message}"); } return null; } /// /// 地址域A解析 /// /// /// public virtual A? Analysis_A(List hexStringList) { try { if (hexStringList.Count > 7) { BaseHexMessage baseHexMessage = new BaseHexMessage { HexMessageList = hexStringList.GetRange(7, 5) // 地址域 5个字节 }; baseHexMessage.HexMessageString = string.Join("", baseHexMessage.HexMessageList); if (baseHexMessage.HexMessageList.Count == 0) return null; A a = new A { BaseHexMessage = baseHexMessage, A1 = baseHexMessage.HexMessageList.ListReverseToStr(0, 2),//.DataConvert(10);//行政区划码A1 A2 = baseHexMessage.HexMessageList.ListReverseToStr(2, 2).PadLeft(5, '0').HexToDec(),//终端地址A2 A3 = Analysis_A3(baseHexMessage.HexMessageList) //主站地址和组地址标志A3 }; a.Code = $"{a.A1.PadLeft(4, '0')}{a.A2.ToString().PadLeft(5, '0')}"; return a; } } catch (Exception ex) { _logger.LogError($"解析Analysis_A错误,报文:{string.Join("", hexStringList)},异常:{ex.Message}"); } return null; } /// /// 站地址和组地址标志A3 /// /// 地址域A集合 /// public virtual A3? Analysis_A3(List hexAList) { try { BaseHexMessage baseHexMessage = new BaseHexMessage { HexMessageList = hexAList.GetRange(4, 1) // 站地址和组地址标志A3 1个字节 }; baseHexMessage.HexMessageString = string.Join("", baseHexMessage.HexMessageList); if (baseHexMessage.HexMessageList.Count == 0) return null; var binStr = baseHexMessage.HexMessageString.HexTo4BinZero(); A3 a3 = new A3 { BaseHexMessage = baseHexMessage, D0 = binStr.Substring(binStr.Length - 1, 1).BinToDec(), D1_D7 = binStr.Substring(0, binStr.Length - 1).BinToDec() }; return a3; } catch (Exception ex) { _logger.LogError($"解析Analysis_A3错误,报文:{string.Join("", hexAList)},异常:{ex.Message}"); } return null; } /// /// AFN_FC功能码 /// /// public virtual AFN_FC? Analysis_AFN_FC(List hexStringList) { try { BaseHexMessage baseHexMessage = new BaseHexMessage { HexMessageList = hexStringList.GetRange(12, 1) //AFN功能码 1个字节 }; baseHexMessage.HexMessageString = string.Join("", baseHexMessage.HexMessageList); if (baseHexMessage.HexMessageList.Count == 0) return null; AFN_FC aFN_FC = new AFN_FC { BaseHexMessage = baseHexMessage, AFN = baseHexMessage.HexMessageString.HexToDec(), }; return aFN_FC; } catch (Exception ex) { _logger.LogError($"解析Analysis_AFN_FC错误,报文:{string.Join("", hexStringList)},异常:{ex.Message}"); } return null; } /// /// 解析帧序列域SEQ /// /// public virtual SEQ? Analysis_SEQ(List hexStringList) { try { BaseHexMessage baseHexMessage = new BaseHexMessage { HexMessageList = hexStringList.GetRange(13, 1) //帧序列域 SEQ 1个字节 }; baseHexMessage.HexMessageString = string.Join("", baseHexMessage.HexMessageList); if (baseHexMessage.HexMessageList.Count == 0) return null; var binStr = baseHexMessage.HexMessageString.HexTo4BinZero(); SEQ seq = new SEQ { PSEQ = binStr.Substring(binStr.Length - 4, 4).BinToDec(), CON = binStr.Substring(3, 1).BinToDec(), FIN = binStr.Substring(2, 1).BinToDec(), FIR = binStr.Substring(1, 1).BinToDec(), TpV = binStr.Substring(0, 1).BinToDec() }; return seq; } catch (Exception ex) { _logger.LogError($"解析Analysis_SEQ错误,报文:{string.Join("", hexStringList)},异常:{ex.Message}"); } return null; } /// /// 数据单元标识及数据单元数据 /// public virtual UnitData? Analysis_UnitData(List hexStringList) { try { UnitData unitData = new UnitData { HexMessageList = hexStringList.GetRange(14, hexStringList.Count - 14 - 2) //总数字节数-固定长度报文头-控制域C-地址域A-校验和CS-结束字符(16H) }; unitData.HexMessageString = string.Join("", unitData.HexMessageList); if (unitData.HexMessageList.Count == 0) return null; return unitData; } catch (Exception ex) { _logger.LogError($"解析Analysis_UnitData错误,报文:{string.Join("", hexStringList)},异常:{ex.Message}"); } return null; } /// /// 信息点DA Pn /// /// public virtual DA? Analysis_DA(List hexStringList) { try { BaseHexMessage baseHexMessage = new BaseHexMessage { HexMessageList = hexStringList.GetRange(14, 2) //信息点DA Pn 2个字节 }; baseHexMessage.HexMessageString = string.Join("", baseHexMessage.HexMessageList); if (baseHexMessage.HexMessageList.Count == 0) return null; var da1 = baseHexMessage.HexMessageList[0]; var da2 = baseHexMessage.HexMessageList[1]; DA da = new DA() { BaseHexMessage = baseHexMessage, Pn = CalculatePn(da1, da2) }; return da; } catch (Exception ex) { _logger.LogError($"解析Analysis_DA错误,报文:{string.Join("", hexStringList)},异常:{ex.Message}"); } return null; } /// /// 信息类DT Fn /// /// public virtual DT? Analysis_DT(List hexStringList) { try { BaseHexMessage baseHexMessage = new BaseHexMessage { HexMessageList = hexStringList.GetRange(16, 2) //信息类DT Fn 2个字节 }; baseHexMessage.HexMessageString = string.Join("", baseHexMessage.HexMessageList); if (baseHexMessage.HexMessageList.Count == 0) return null; var dt1 = baseHexMessage.HexMessageList[0]; var dt2 = baseHexMessage.HexMessageList[1]; DT dt = new DT() { BaseHexMessage = baseHexMessage, Fn = CalculateFn(dt1, dt2) }; return dt; } catch (Exception ex) { _logger.LogError($"解析Analysis_DT错误,报文:{string.Join("", hexStringList)},异常:{ex.Message}"); } return null; } /// /// 计算Pn /// /// /// /// public int CalculatePn(string da1, string da2) => (da2.HexToDec() - 1) * 8 + (8 - da1.HexTo4BinZero().IndexOf(da1.Equals("00") ? "0" : "1")); /// /// 计算Fn /// /// /// /// public int CalculateFn(string dt1, string dt2) => dt2.HexToDec() * 8 + (8 - dt1.HexTo4BinZero().IndexOf("1")); } }