using log4net; using Sensus.iPerl.NfcHandler; using Sensus.iPerl.RfidCom.Exceptions; using System; using System.Globalization; using System.Text; using System.Threading; using static Sensus.iPerl.NfcHandler.MCI_Protocol; namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead { internal class NfcServices { protected static readonly ILog rfidDataLogger = LogManager.GetLogger("RfidData"); internal static int ReadRequest(TestMethodCfg cfg, IperlHead iperlHead, MCI_Protocol.StructName structName, int offset, int length, out byte[] buffer) { for (int i = 0; i < cfg.MaxCommRetries; i++) { NfcDataHandler _nfcDataHandler = new NfcDataHandler(); MessageEventHandlers(_nfcDataHandler); CR95HF_MessageEventHandlers(_nfcDataHandler._CR95HF_Reader); ST25DV_MessageEventHandlers(_nfcDataHandler._ST25DV_Device); MCI_MessageEventHandlers(_nfcDataHandler._MCI_Protocol); NFCHeadConfig_MessageEventHandlers(_nfcDataHandler._NFCHead_Config); try { rfidDataLogger.Info($"NFC COM{iperlHead.RfidComPortNr} ReadRequest : {structName}, {offset}, {length}"); OpenConnection(_nfcDataHandler, cfg, iperlHead); buffer = MciRead(_nfcDataHandler, cfg, structName, (ushort)offset, length); _nfcDataHandler.RFProtocolOFF(); // turn off rf antenna due to possible interference CloseComPort(_nfcDataHandler); rfidDataLogger.Info($"NFC COM{iperlHead.RfidComPortNr} ReadRequest : {structName}, {offset}, {length} ; Response= {ByteArrayToHexString(buffer)} ; Error: {_nfcDataHandler.LastErrorMessage}"); if (_nfcDataHandler.LastErrorCode != 0) { throw new RfidValidationException(_nfcDataHandler.LastErrorMessage); } return Convert.ToInt32(_nfcDataHandler.LastErrorCode); //return 0; } catch (RfidValidationException) { Thread.Sleep(cfg.WaitTimeAfterFailure); } catch (Exception ex) { rfidDataLogger.Error($"NFC COM{iperlHead.RfidComPortNr} ReadRequest Error: {ex.Message}"); buffer = new byte[length]; return 3; } } buffer = new byte[length]; return 3; } internal static int WriteRequest(TestMethodCfg cfg, IperlHead iperlHead, MCI_Protocol.StructName structName, int offset, int length, byte[] buffer) { NfcDataHandler _nfcDataHandler = new NfcDataHandler(); MessageEventHandlers(_nfcDataHandler); CR95HF_MessageEventHandlers(_nfcDataHandler._CR95HF_Reader); ST25DV_MessageEventHandlers(_nfcDataHandler._ST25DV_Device); MCI_MessageEventHandlers(_nfcDataHandler._MCI_Protocol); NFCHeadConfig_MessageEventHandlers(_nfcDataHandler._NFCHead_Config); try { rfidDataLogger.Info($"NFC COM{iperlHead.RfidComPortNr} WriteRequest : {structName}, {offset}, {length}, {ByteArrayToHexString(buffer)}"); OpenConnection(_nfcDataHandler, cfg, iperlHead); MciWrite(_nfcDataHandler, cfg, structName, (ushort)offset, length, buffer); _nfcDataHandler.RFProtocolOFF(); // turn off rf antenna due to possible interference CloseComPort(_nfcDataHandler); return 0; } catch (Exception ex) { rfidDataLogger.Error($"NFC COM{iperlHead.RfidComPortNr} WriteRequest Error: {ex.Message}"); return 3; } } private static void OpenConnection(NfcDataHandler nfcDataHandler, TestMethodCfg cfg, IperlHead iperlHead) { string comPort = $"COM{iperlHead.RfidComPortNr}"; int retryCount = 0 ; Open: nfcDataHandler.Close(); Thread.Sleep(100); if (nfcDataHandler.OpenConnection(comPort, cfg.BaudRate, cfg.DataBits, cfg.ParityBit, cfg.StopBits)) { rfidDataLogger.Info($"NFC COM{iperlHead.RfidComPortNr} Port Open"); if (nfcDataHandler.ConnectReader()) { rfidDataLogger.Info($"NFC COM{iperlHead.RfidComPortNr} Reader connected"); if (!nfcDataHandler.ConnectDevice()) { rfidDataLogger.Error($"NFC COM{iperlHead.RfidComPortNr} Error connect device."); for (int i = 0; i < cfg.MaxCommRetries; i++) { if (nfcDataHandler.Echo()) break; } } } else { retryCount++; rfidDataLogger.Error($"NFC COM{iperlHead.RfidComPortNr} Error connect reader. Reconnect comport {retryCount}"); if (retryCount < cfg.MaxCommRetries) { nfcDataHandler.Close(); iperlHead.ResetNfcInterface(); // reset NFC head via optoport - switch to RFID and back to NFC interface goto Open; } } } else rfidDataLogger.Error($"Open NFC COM{iperlHead.RfidComPortNr} Port Failed"); } private static void CloseComPort(NfcDataHandler nfcDataHandler) { nfcDataHandler.Close(); } private static byte[] MciRead(NfcDataHandler nfcDataHandler, TestMethodCfg cfg, StructName structName, ushort offset, int length) { bool isReadValues = false; int retryCount = 0; Read: try { isReadValues = false; long num1 = (long)length; int timeoutMs = 4000; byte payloadlength = Convert.ToByte(num1.ToString("X2"), 16); if (nfcDataHandler.MCI_Read(structName, offset, payloadlength, timeoutMs)) { byte[] lastData = nfcDataHandler.LastData; if ((long)lastData.Length >= num1) { rfidDataLogger.Info($"COM: MciRead ({structName},{offset},{length}) = {ByteArrayToHexString(lastData)}"); return lastData; } else rfidDataLogger.Info($"COM: MciRead ({structName},{offset},{length}) = {ByteArrayToHexString(lastData)}"); } else if (nfcDataHandler.LastErrorCode == (byte)0) { rfidDataLogger.Info($"MCI Error: Unidentified"); retryCount++; if (retryCount < cfg.MaxCommRetries) goto Read; } else { rfidDataLogger.Info("Last error message: " + nfcDataHandler.LastErrorMessage); retryCount++; if (retryCount < cfg.MaxCommRetries) goto Read; } } catch (Exception ex) { rfidDataLogger.Error("MciRead Last error message: " + ex.Message); retryCount++; if (retryCount < cfg.MaxCommRetries) goto Read; } return new byte[length]; } private static void MciWrite(NfcDataHandler nfcDataHandler, TestMethodCfg cfg, MCI_Protocol.StructName structName, ushort offset, int length, byte[] payload) { int retryCount = 0; Write: try { long num1 = (long)length; int timeoutMs = 4000; byte payloadlength = Convert.ToByte(num1); if ((int)payloadlength != payload.Length) rfidDataLogger.Error("Insufficient Payload -- Payload lenth : " + (object)payload.Length); else if (nfcDataHandler.MCI_Write(structName, offset, payloadlength, payload, timeoutMs)) { // OK } else if (nfcDataHandler.LastErrorCode > (byte)0) { rfidDataLogger.Error("Last error message: " + nfcDataHandler.LastErrorMessage); //int num2 = (int)MessageBox.Show(this._nfcDataHandler.LastErrorMessage); } } catch (Exception ex) { rfidDataLogger.Error("MciWrite error message: " + ex.Message); retryCount++; if (retryCount < cfg.MaxCommRetries) goto Write; } } private static void MciWriteCommand(NfcDataHandler nfcDataHandler, byte commandcode) { try { ushort offset = 0; int timeoutMs = 4000; byte payloadlength = 1; byte[] payload = new byte[1] { commandcode }; if (nfcDataHandler.MCI_Write(MCI_Protocol.StructName.Command, offset, payloadlength, payload, timeoutMs) || nfcDataHandler.LastErrorCode <= (byte)0) return; rfidDataLogger.Error("MciWriteCommand Last error message: " + nfcDataHandler.LastErrorMessage); } catch (Exception ex) { rfidDataLogger.Error("MciWriteCommand Last error message: " + ex.Message); } } public static string ByteArrayToHexString(byte[] data) { StringBuilder stringBuilder = new StringBuilder(); foreach (byte num in data) stringBuilder.Append(num.ToString("X2")); return stringBuilder.ToString(); } private static byte[] BuildPayLoad(string strPayLoad, int length) { byte[] collection; if (strPayLoad.Split(':').Length > 1) { uint timestamp = ConvertDateTimeToTimestamp(Convert.ToDateTime(DateTime.ParseExact(strPayLoad, "HH:mm:ss dd/MM/yyyy", (IFormatProvider)CultureInfo.InvariantCulture))); byte[] bytes = BitConverter.GetBytes(timestamp); return bytes; } else if (strPayLoad.Split(',').Length > 1) { string[] strArray = strPayLoad.Split(','); collection = new byte[strArray.Length]; for (int index3 = 0; index3 < strArray.Length; ++index3) collection[index3] = Convert.ToByte(strArray[index3], 16); return collection; } else { //int num = strPayLoad.Split(',').Length; collection = HexStringToByteArray(strPayLoad.Substring(strPayLoad.Length - length * 2).ToUpper()); Array.Reverse((Array)collection); return collection; } } public static byte[] HexStringToByteArray(string hexString) { int length = hexString.Length; byte[] byteArray = new byte[length / 2]; for (int startIndex = 0; startIndex < length; startIndex += 2) byteArray[startIndex / 2] = Convert.ToByte(hexString.Substring(startIndex, 2), 16); return byteArray; } private static uint ConvertDateTimeToTimestamp(DateTime datetime) { TimeSpan utcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now); return (uint)((datetime - new DateTime(2000, 1, 1, 0, 0, 0).ToLocalTime()).TotalSeconds + utcOffset.TotalSeconds); } #region EventHandlers public static void MCI_MessageEventHandlers(MCI_Protocol e) { DelNfc_MCI_MessageHandler mciMessageHandler = new DelNfc_MCI_MessageHandler(OnHandler); e.MessageEvent += mciMessageHandler; } public static void ST25DV_MessageEventHandlers(ST25DV_Device e) { DelNfc_ST25DV_MessageHandler dvMessageHandler = new DelNfc_ST25DV_MessageHandler(OnHandler); e.MessageEvent += dvMessageHandler; } public static void CR95HF_MessageEventHandlers(CR95HF_Reader e) { DelNfc_CR95HF_MessageHandler hfMessageHandler = new DelNfc_CR95HF_MessageHandler(OnHandler); e.MessageEvent += hfMessageHandler; } public static void NFCHeadConfig_MessageEventHandlers(NFCHeadConfig e) { DelNfc_NFCHeadConfig_MessageHandler configMessageHandler = new DelNfc_NFCHeadConfig_MessageHandler(OnHandler); e.MessageEvent += configMessageHandler; } public static void MessageEventHandlers(NfcDataHandler e) { DelNfcMessageHandler nfcMessageHandler = new DelNfcMessageHandler(OnHandler); e.MessageEvent += nfcMessageHandler; } public static void OnHandler(object sender, NfcMessageEventArgs e) { if (e.Message == null) return; string message = e.Message.Replace("\n", " ").Replace("\r", ""); rfidDataLogger.Debug(message); } #endregion } }