using Sensus.iPerl.RfidCom.Exceptions; using Sensus.iPerl.RfidCom.Helper; using Sensus.iPerl.RfidCom; using System; using System.Text.RegularExpressions; using System.Threading; using log4net; namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead { internal class RfidServices { protected static readonly ILog rfidDataLogger = LogManager.GetLogger("RfidData"); private static readonly ILog log = LogManager.GetLogger(typeof(iPerlCommunicationForm)); internal static int ReadRequest(TestMethodCfg cfg, IperlHead iperlHead, MessageID messageID, int offset, int length, out byte[] buffer) { for (int i = 0; i < cfg.MaxCommRetries; i++) { rfidDataLogger.Error($"{iperlHead.CommInterface} Start {i} reading: COM{iperlHead.RfidComPortNr}: ReadRequestPort ({messageID},{offset}, {length}... timeout {cfg.CommTimeout})"); using (RfidLogic writer = new RfidLogic($"COM{iperlHead.RfidComPortNr}")) { try { byte[] response = writer.ReadRequest((byte)messageID, offset, length, cfg.CommTimeout); string hexString = RfidHelper.ConvertByteArrayToHexString(response); string swapHexString = RfidHelper.SwapHexcode(hexString); string decString = RfidHelper.HexLiteral2Unsigned(RfidHelper.SwapHexcode(hexString)).ToString(); if (length > 10) { //if the result only contains "00"s we are working on the wrong COM port // or the module just isn't connected if (Regex.IsMatch(hexString, @"^(00)\1+$")) { rfidDataLogger.Error($"COM{iperlHead.RfidComPortNr}: ReadRequestPort ({messageID},...) <- Error: No RFID signal."); throw new RfidValidationException("Error_Rfid_NoSignal"); } //if the result only contains "03"s the meter did not answer. // Might be due to the module being positioned incorrectly. if (Regex.IsMatch(hexString, @"^(03)\1+$")) { rfidDataLogger.Error($"COM{iperlHead.RfidComPortNr}: ReadRequestPort ({messageID},...) <- Error: No meter signal."); throw new RfidValidationException("Error_Rfid_NoAnswerFromMeter"); } } writer.ClosePort(); buffer = response; rfidDataLogger.Info($"{iperlHead.Name} ({iperlHead.SerialNr}): ReadRequestPort(COM{iperlHead.RfidComPortNr},...) returned HEX: {hexString}; SwapHexCodeToDecimal: {decString}"); return 0; } catch (RfidDataNotAvailableException) { if (/*RfidHelper.IsPassThrough(messageID)*/ messageID == MessageID.ASICRegisterReadTest || messageID == MessageID.RadioPassthrough) { rfidDataLogger.Info($"COM{iperlHead.RfidComPortNr}: ReadRequestPort ({messageID},...) {(i > 0 ? "<- Error: Invalid Pass-Through data." : "<- Info: Wait for Pass-Through data.")}"); Thread.Sleep(cfg.PassThroughWaitTime); } else { Thread.Sleep(cfg.WaitTimeAfterFailure); } } catch (RfidValidationException) { Thread.Sleep(cfg.WaitTimeAfterFailure); } catch (Exception ex) { rfidDataLogger.Error($"COM{iperlHead.RfidComPortNr}: ReadRequestPort ({messageID},...) {ex.Message}"); Thread.Sleep(cfg.WaitTimeAfterFailure); } } } rfidDataLogger.Error($"{iperlHead.CommInterface} reading failed after {cfg.MaxCommRetries} retries: COM{iperlHead.RfidComPortNr}: ReadRequestPort ({messageID},...)"); log.Error($"{iperlHead.CommInterface} reading failed after {cfg.MaxCommRetries} retries: COM{iperlHead.RfidComPortNr}: ReadRequestPort ({messageID},...)"); buffer = new byte[length]; return 3; } internal static int WriteRequest(TestMethodCfg cfg, IperlHead iperlHead, MessageID messageID, int offset, int length, byte[] buffer) { RfidLogic writer = new RfidLogic($"COM{iperlHead.RfidComPortNr}"); string payload = RfidHelper.ConvertByteArrayToHexString(buffer); for (var i = 0; i < cfg.MaxCommRetries; i++) { rfidDataLogger.Error($"{iperlHead.CommInterface} Start {i} writting: COM{iperlHead.RfidComPortNr}: WriteRequest ({messageID},{offset}, {length}, {payload}... timeout {cfg.CommTimeout})"); try { if (writer.ClosePort()) writer.OpenPort(); writer.WriteRequest((byte)messageID, offset, length, buffer, cfg.CommTimeout, false); writer.ClosePort(); rfidDataLogger.InfoFormat($"{iperlHead.Name}({iperlHead.SerialNr},COM{iperlHead.RfidComPortNr}): WriteRequestPort({messageID}, {offset}, {length}, {payload})"); return 0; } catch (Exception ex) { if (messageID == MessageID.RadioPassthrough || messageID == MessageID.ASICRegisterReadTest) { Thread.Sleep(1500); } else { rfidDataLogger.Error($"COM{iperlHead.RfidComPortNr}: Error: {ex.Message}"); Thread.Sleep(cfg.WaitTimeAfterFailure); if (i > 1) { rfidDataLogger.Error($"COM{iperlHead.RfidComPortNr}: Reopen the com port."); writer.ClosePort(); } } } } writer.ClosePort(); rfidDataLogger.Error($"RFID writing failed after {cfg.MaxCommRetries} retries: COM{iperlHead.RfidComPortNr}: WriteRequestPort ({messageID},...) {System.Text.Encoding.UTF8.GetString(buffer)}"); log.Error($"RFID writing failed after {cfg.MaxCommRetries} retries: COM{iperlHead.RfidComPortNr}: WriteRequestPort ({messageID},...) {System.Text.Encoding.UTF8.GetString(buffer)}"); return 2; } } }