Compare commits

..
6 Commits
Author SHA1 Message Date
michal d3acd5ebb3 Working NfcC7_DLL, tests, clean up
"Remove unused NfcHanler classes and utilities"

This commit deletes several obsolete and unused files from the NfcHanler directory, including utility classes, enums, and a large command handling class. This cleanup improves code maintainability by eliminating unnecessary dependencies and clutter.
2025-10-14 13:15:30 +02:00
michal d2ca40d151 Add initial implementation for AppDiagnostic project
This commit introduces the AppDiagnostic project structure, including core components like `MainForm`, logging utilities (`LogAdapter`, `LogFilter`), and configuration files. It integrates with `log4net` for logging and uses `SharedComponents` for shared utilities.
2025-09-07 22:13:57 +02:00
michal 64bfe937fa Add FluentNHibernate and log4net dependencies
This commit restores the FluentNHibernate package in various configurations and adds log4net references across multiple projects for enhanced logging. Additionally, several exceptions were reformatted to use `string.Format` for consistency. Updates to the solution structure and new configuration files support these changes.
2025-01-23 16:50:14 +01:00
michal 1440e08341 Remove outdated NHibernate and FluentNHibernate config files
Deleted deprecated configuration files related to FireBird and FluentNHibernate. These files are no longer required for the project and their removal helps streamline the codebase, reducing clutter and potential confusion.
2025-01-16 15:44:01 +01:00
michal 3da36187f9 Add IntelliJ config and gitignore files for projects
Introduce `.idea` configuration files and `.gitignore` entries for `NfcS5_DLL` and `TBF` projects. These changes include settings for encodings, VCS mappings, and index layout configurations. Helps streamline project setup and improve tooling compatibility.
2024-12-22 12:32:34 +01:00
Jan Augustin 13bf73104f Ingo Fritz - Add rest client for security server 2024-07-25 12:14:58 +02:00
15 changed files with 646 additions and 439 deletions
+13
View File
@@ -0,0 +1,13 @@
# Default ignored files
/shelf/
/workspace.xml
# Rider ignored files
/projectSettingsUpdater.xml
/.idea.NfcS5_DLL.iml
/modules.xml
/contentModel.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
</project>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="UserContentModel">
<attachedFolders />
<explicitIncludes />
<explicitExcludes />
</component>
</project>
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>
+10
View File
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?><configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="NHibernate" publicKeyToken="aa95f207798dfdb4" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.5.0.0" newVersion="5.5.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Binary file not shown.
Binary file not shown.
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

+248 -248
View File
@@ -1,249 +1,249 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.IO.Ports;
//*****************************************************************************
// Copyright 2020 Sensus GmbH Ludwigshafen. All rights reserved.
// Author: Venkat, Rajeshwar
//*****************************************************************************
namespace Sensus.iPerl.NfcHandler
{
public class CR95HF_Reader
{
private readonly byte [] CR95HF_CMD_ECHO = { 0x55 };
private readonly byte[] CR95HF_CMD_IDN = { 0x01, 0x00 }; //CommandCode(0x01), Length(0x00)
private readonly byte[] CR95HF_CMD_PROTOCOL_SELECT_ON = { 0x02, 0x02, 0x01, 0x0D }; //CommandCode(0x02), Length(0x02), ISO/IEC 15693(0x01), 26 Kbps H, Wait for SOF, 10% modulation, Single subcarrier S, CRC appended (0x0D)
private readonly byte[] CR95HF_CMD_PROTOCOL_SELECT_OFF = { 0x02, 0x02, 0x00, 0x00 }; //CommandCode(0x02), Length(0x02), Protocol off (0x00), Protocol off (0x00)
private List<byte> CR95HF_CMD_SEND_RECEIVE = new List<byte>(); // Command code (0x04), Length (this is number of bytes after this length byte), REQUEST_FLAGS(0x02) and payload (this varies based on device command)
private readonly byte REQUEST_FLAGS = 0x02; // Single subcarrier freq, High data rate, No Inventory/ProtExtn/Select/Address/Option flags
private SERIAL_Driver _SERIAL_Driver;
public event DelNfc_CR95HF_MessageHandler MessageEvent;
private static readonly Dictionary<byte, string> CR95HF_ErrorCodes = new Dictionary<byte, string>
{
{ 0x00 , "Success, No error" },
{ 0x80 , "Success, No error" },
{ 0xA0 , "Success, No error" },
{ 0xC0 , "Success, No error" },
{ 0x82 , "Invalid command length" },
{ 0x83 , "Invalid protocol"},
{ 0x63 , "EEmdSOFerror23, SOF error in high part(duration 2 to 3 etu) in ISO/IEC 14443B"},
{ 0x65 , "EEmdSOFerror10, SOF error in low part(duration 10 to 11 etu) in ISO/IEC 14443B"},
{ 0x66 , "EEmdEgt error, Extended Guard Time error in ISO/IEC 14443B"},
{ 0x67 , "ETr1 Too Big Too long, TR1 send by the card, reception stopped in ISO/IEC 14443BT"},
{ 0x68 , "ETr1Too small Too small, TR1 send by the card in ISO/IEC 14443B"},
{ 0x71 , "EinternalError, Wrong frame format decoded"},
{ 0x85 , "EUserStop, Stopped by user(used only in Card mode)"},
{ 0x86 , "ECommError, Hardware communication error"},
{ 0x87 , "EFrameWaitTOut,Frame wait time out (no valid reception)"},
{ 0x88 , "EInvalidSof,Invalid SOF" },
{ 0x89 , "EBufOverflow,Too many bytes received and data still arriving" },
{ 0x8A , "EFramingError,if start bit = 1 or stop bit = 0"},
{ 0x8B , "EEgtError,EGT time out" },
{ 0x8C , "EInvalidLen,Valid for ISO/IEC 18092, if Length<3" },
{ 0x8D , "ECrcError,CRC error, Valid only for ISO/IEC 18092" },
{ 0x8E , "ERecvLost,CRC error,When reception is lost without EOF received(or subcarrier was lost)"},
{ 0x8F , "ENoField,CRC error,When Listen command detects the absence of external field)"},
{ 0x90 , "EUnintByte,Residual bits in last byte. Useful for ACK/NAK reception of ISO/IEC 14443 Type A"},
{ 0xFF , "Invalid COM port, request Failed" },
};
public CR95HF_Reader(SERIAL_Driver serialdriver)
{
_SERIAL_Driver = serialdriver;
}
#region Message Event
private void OnMessageEvent(string message)
{
NfcMessageEventArgs e = new NfcMessageEventArgs();
e.Message = message;
if (MessageEvent != null)
{
MessageEvent(this, e);
}
e = null;
}
#endregion
public bool OpenConnection(string comport, int baudrate, int databits, Parity parity, StopBits stopbits)
{
return _SERIAL_Driver.OpenConnection(comport, baudrate, databits, parity, stopbits);//Port Intialization and Port Open;
}
public bool CR95HF_Connect()
{
byte[] bytesReceived;
if (_SERIAL_Driver.isOpen())
{
//OnMessageEvent("Tx- " + Tools.ByteArrayToHexString(CR95HF_CMD_IDN));
_SERIAL_Driver.SendMessage(CR95HF_CMD_IDN, CR95HF_CMD_IDN.Length);
if (_SERIAL_Driver.GetRawData().Length == 0) return false;
bytesReceived = _SERIAL_Driver.GetRawData();
//OnMessageEvent("Rx- " + Tools.ByteArrayToHexString(bytesReceived));
if (bytesReceived.Length == 17 && (bytesReceived[0] == 0x00 || bytesReceived[0] == 0x80))
{
string strReader = System.Text.Encoding.ASCII.GetString(bytesReceived);
strReader = strReader.Substring(2, 12);
OnMessageEvent("CombiHead '" + strReader + "'");
}
else
{
if (CR95HF_ErrorCodes.ContainsKey(bytesReceived[0]))
OnMessageEvent("NFC CR95HF error: " + CR95HF_ErrorCodes[bytesReceived[0]]);
else
OnMessageEvent("NFC CR95HF error: Unidentified");
return false;
}
//OnMessageEvent("Tx- " + Tools.ByteArrayToHexString(CR95HF_CMD_PROTOCOL_SELECT_ON));
_SERIAL_Driver.SendMessage(CR95HF_CMD_PROTOCOL_SELECT_ON, CR95HF_CMD_PROTOCOL_SELECT_ON.Length);
if (_SERIAL_Driver.GetRawData().Length == 0) return false;
bytesReceived = _SERIAL_Driver.GetRawData();
//OnMessageEvent("Rx- " + Tools.ByteArrayToHexString(bytesReceived));
if ((bytesReceived[0] != 0x00) && (bytesReceived[0] != 0x80))
{
if (CR95HF_ErrorCodes.ContainsKey(bytesReceived[0]))
OnMessageEvent("NFC CR95HF error: " + CR95HF_ErrorCodes[bytesReceived[0]]);
else
OnMessageEvent("NFC CR95HF error: Unidentified");
return false;
}
}
else
{
OnMessageEvent(_SERIAL_Driver.ErrorMessage);
return false;
}
OnMessageEvent("NFC CR95HF: Protocol ON");
return true;
}
public bool CR95HF_RFProtocolOn()
{
byte[] bytesReceived;
if (_SERIAL_Driver.isOpen())
{
//OnMessageEvent("Tx- " + Tools.ByteArrayToHexString(CR95HF_CMD_PROTOCOL_SELECT_ON));
_SERIAL_Driver.SendMessage(CR95HF_CMD_PROTOCOL_SELECT_ON, CR95HF_CMD_PROTOCOL_SELECT_ON.Length);
if (_SERIAL_Driver.GetRawData().Length == 0) return false;
bytesReceived = _SERIAL_Driver.GetRawData();
//OnMessageEvent("Rx- " + Tools.ByteArrayToHexString(bytesReceived));
if ((bytesReceived[0] != 0x00) && (bytesReceived[0] != 0x80))
{
if (CR95HF_ErrorCodes.ContainsKey(bytesReceived[0]))
OnMessageEvent("NFC CR95HF error: " + CR95HF_ErrorCodes[bytesReceived[0]]);
else
OnMessageEvent("NFC CR95HF error: Unidentified");
return false;
}
}
else
{
OnMessageEvent(_SERIAL_Driver.ErrorMessage);
return false;
}
return true;
}
public bool CR95HF_RFProtocolOff()
{
byte[] bytesReceived;
if (_SERIAL_Driver.isOpen())
{
//OnMessageEvent("Tx- " + Tools.ByteArrayToHexString(CR95HF_CMD_PROTOCOL_SELECT_OFF));
_SERIAL_Driver.SendMessage(CR95HF_CMD_PROTOCOL_SELECT_OFF, CR95HF_CMD_PROTOCOL_SELECT_OFF.Length);
if (_SERIAL_Driver.GetRawData().Length == 0) return false;
bytesReceived = _SERIAL_Driver.GetRawData();
//OnMessageEvent("Rx- " + Tools.ByteArrayToHexString(bytesReceived));
if ((bytesReceived[0] != 0x00) && (bytesReceived[0] != 0x80))
{
if (CR95HF_ErrorCodes.ContainsKey(bytesReceived[0]))
OnMessageEvent("NFC CR95HF error: " + CR95HF_ErrorCodes[bytesReceived[0]]);
else
OnMessageEvent("NFC CR95HF error: Unidentified");
return false;
}
}
else
{
OnMessageEvent(_SERIAL_Driver.ErrorMessage);
return false;
}
return true;
}
public bool CR95HF_SendRecv(byte[] fromDevice, out byte[] toDevice)
{
CR95HF_CMD_SEND_RECEIVE = new List<byte>();
toDevice = null;
if (_SERIAL_Driver.isOpen())
{
CR95HF_CMD_SEND_RECEIVE.Add(0x04);//Command Code
CR95HF_CMD_SEND_RECEIVE.Add((byte)(1 + fromDevice.Length)); // This is bytes from device + 1 (because request flags byte added here)
CR95HF_CMD_SEND_RECEIVE.Add(REQUEST_FLAGS);
CR95HF_CMD_SEND_RECEIVE.AddRange(fromDevice);
//OnMessageEvent("Tx- " + Tools.ByteArrayToHexString(CR95HF_CMD_SEND_RECEIVE.ToArray()));
_SERIAL_Driver.SendMessage(CR95HF_CMD_SEND_RECEIVE.ToArray(), (3 + fromDevice.Length)); // This is bytes from device + 3 (because request flags + length + reader command)
if (_SERIAL_Driver.GetRawData().Length == 0) return false;
byte[] bytesReceived = _SERIAL_Driver.GetRawData();
//OnMessageEvent("Rx- " + Tools.ByteArrayToHexString(bytesReceived));
if ((bytesReceived[0] == 0x00) || (bytesReceived[0] == 0x80) || (bytesReceived[0] == 0xA0) || (bytesReceived[0] == 0xC0))
{
toDevice = new byte[bytesReceived[1]];
for (int i = 0; i < Convert.ToInt32(bytesReceived[1]); i++)
{
toDevice[i] = bytesReceived[2 + i];
}
}
else
{
if (CR95HF_ErrorCodes.ContainsKey(bytesReceived[0]))
OnMessageEvent("NFC CR95HF error: " + CR95HF_ErrorCodes[bytesReceived[0]]);
else
OnMessageEvent("NFC CR95HF error: Unidentified");
return false;
}
}
else
{
OnMessageEvent(_SERIAL_Driver.ErrorMessage);
return false;
}
return true;
}
public bool CR95HF_Echo()
{
if (_SERIAL_Driver.isOpen())
{
if (_SERIAL_Driver.SendMessage(CR95HF_CMD_ECHO, 1))
{
if (_SERIAL_Driver.GetRawData().Length == 0) return false;
byte[] bytesReceived = _SERIAL_Driver.GetRawData();
if ((bytesReceived.Length == 1) && (bytesReceived[0] == CR95HF_CMD_ECHO[0]))
return true;
}
}
else
{
OnMessageEvent(_SERIAL_Driver.ErrorMessage);
return false;
}
return false;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.IO.Ports;
//*****************************************************************************
// Copyright 2020 Sensus GmbH Ludwigshafen. All rights reserved.
// Author: Venkat, Rajeshwar
//*****************************************************************************
namespace Sensus.iPerl.NfcHandler
{
public class CR95HF_Reader
{
private readonly byte [] CR95HF_CMD_ECHO = { 0x55 };
private readonly byte[] CR95HF_CMD_IDN = { 0x01, 0x00 }; //CommandCode(0x01), Length(0x00)
private readonly byte[] CR95HF_CMD_PROTOCOL_SELECT_ON = { 0x02, 0x02, 0x01, 0x0D }; //CommandCode(0x02), Length(0x02), ISO/IEC 15693(0x01), 26 Kbps H, Wait for SOF, 10% modulation, Single subcarrier S, CRC appended (0x0D)
private readonly byte[] CR95HF_CMD_PROTOCOL_SELECT_OFF = { 0x02, 0x02, 0x00, 0x00 }; //CommandCode(0x02), Length(0x02), Protocol off (0x00), Protocol off (0x00)
private List<byte> CR95HF_CMD_SEND_RECEIVE = new List<byte>(); // Command code (0x04), Length (this is number of bytes after this length byte), REQUEST_FLAGS(0x02) and payload (this varies based on device command)
private readonly byte REQUEST_FLAGS = 0x02; // Single subcarrier freq, High data rate, No Inventory/ProtExtn/Select/Address/Option flags
private SERIAL_Driver _SERIAL_Driver;
public event DelNfc_CR95HF_MessageHandler MessageEvent;
private static readonly Dictionary<byte, string> CR95HF_ErrorCodes = new Dictionary<byte, string>
{
{ 0x00 , "Success, No error" },
{ 0x80 , "Success, No error" },
{ 0xA0 , "Success, No error" },
{ 0xC0 , "Success, No error" },
{ 0x82 , "Invalid command length" },
{ 0x83 , "Invalid protocol"},
{ 0x63 , "EEmdSOFerror23, SOF error in high part(duration 2 to 3 etu) in ISO/IEC 14443B"},
{ 0x65 , "EEmdSOFerror10, SOF error in low part(duration 10 to 11 etu) in ISO/IEC 14443B"},
{ 0x66 , "EEmdEgt error, Extended Guard Time error in ISO/IEC 14443B"},
{ 0x67 , "ETr1 Too Big Too long, TR1 send by the card, reception stopped in ISO/IEC 14443BT"},
{ 0x68 , "ETr1Too small Too small, TR1 send by the card in ISO/IEC 14443B"},
{ 0x71 , "EinternalError, Wrong frame format decoded"},
{ 0x85 , "EUserStop, Stopped by user(used only in Card mode)"},
{ 0x86 , "ECommError, Hardware communication error"},
{ 0x87 , "EFrameWaitTOut,Frame wait time out (no valid reception)"},
{ 0x88 , "EInvalidSof,Invalid SOF" },
{ 0x89 , "EBufOverflow,Too many bytes received and data still arriving" },
{ 0x8A , "EFramingError,if start bit = 1 or stop bit = 0"},
{ 0x8B , "EEgtError,EGT time out" },
{ 0x8C , "EInvalidLen,Valid for ISO/IEC 18092, if Length<3" },
{ 0x8D , "ECrcError,CRC error, Valid only for ISO/IEC 18092" },
{ 0x8E , "ERecvLost,CRC error,When reception is lost without EOF received(or subcarrier was lost)"},
{ 0x8F , "ENoField,CRC error,When Listen command detects the absence of external field)"},
{ 0x90 , "EUnintByte,Residual bits in last byte. Useful for ACK/NAK reception of ISO/IEC 14443 Type A"},
{ 0xFF , "Invalid COM port, request Failed" },
};
public CR95HF_Reader(SERIAL_Driver serialdriver)
{
_SERIAL_Driver = serialdriver;
}
#region Message Event
private void OnMessageEvent(string message)
{
NfcMessageEventArgs e = new NfcMessageEventArgs();
e.Message = message;
if (MessageEvent != null)
{
MessageEvent(this, e);
}
e = null;
}
#endregion
public bool OpenConnection(string comport, int baudrate, int databits, Parity parity, StopBits stopbits)
{
return _SERIAL_Driver.OpenConnection(comport, baudrate, databits, parity, stopbits);//Port Intialization and Port Open;
}
public bool CR95HF_Connect()
{
byte[] bytesReceived;
if (_SERIAL_Driver.isOpen())
{
//OnMessageEvent("Tx- " + Tools.ByteArrayToHexString(CR95HF_CMD_IDN));
_SERIAL_Driver.SendMessage(CR95HF_CMD_IDN, CR95HF_CMD_IDN.Length);
if (_SERIAL_Driver.GetRawData().Length == 0) return false;
bytesReceived = _SERIAL_Driver.GetRawData();
//OnMessageEvent("Rx- " + Tools.ByteArrayToHexString(bytesReceived));
if (bytesReceived.Length == 17 && (bytesReceived[0] == 0x00 || bytesReceived[0] == 0x80))
{
string strReader = System.Text.Encoding.ASCII.GetString(bytesReceived);
strReader = strReader.Substring(2, 12);
OnMessageEvent("CombiHead '" + strReader + "'");
}
else
{
if (CR95HF_ErrorCodes.ContainsKey(bytesReceived[0]))
OnMessageEvent("NFC CR95HF error: " + CR95HF_ErrorCodes[bytesReceived[0]]);
else
OnMessageEvent("NFC CR95HF error: Unidentified");
return false;
}
//OnMessageEvent("Tx- " + Tools.ByteArrayToHexString(CR95HF_CMD_PROTOCOL_SELECT_ON));
_SERIAL_Driver.SendMessage(CR95HF_CMD_PROTOCOL_SELECT_ON, CR95HF_CMD_PROTOCOL_SELECT_ON.Length);
if (_SERIAL_Driver.GetRawData().Length == 0) return false;
bytesReceived = _SERIAL_Driver.GetRawData();
//OnMessageEvent("Rx- " + Tools.ByteArrayToHexString(bytesReceived));
if ((bytesReceived[0] != 0x00) && (bytesReceived[0] != 0x80))
{
if (CR95HF_ErrorCodes.ContainsKey(bytesReceived[0]))
OnMessageEvent("NFC CR95HF error: " + CR95HF_ErrorCodes[bytesReceived[0]]);
else
OnMessageEvent("NFC CR95HF error: Unidentified");
return false;
}
}
else
{
OnMessageEvent(_SERIAL_Driver.ErrorMessage);
return false;
}
OnMessageEvent("NFC CR95HF: Protocol ON");
return true;
}
public bool CR95HF_RFProtocolOn()
{
byte[] bytesReceived;
if (_SERIAL_Driver.isOpen())
{
//OnMessageEvent("Tx- " + Tools.ByteArrayToHexString(CR95HF_CMD_PROTOCOL_SELECT_ON));
_SERIAL_Driver.SendMessage(CR95HF_CMD_PROTOCOL_SELECT_ON, CR95HF_CMD_PROTOCOL_SELECT_ON.Length);
if (_SERIAL_Driver.GetRawData().Length == 0) return false;
bytesReceived = _SERIAL_Driver.GetRawData();
//OnMessageEvent("Rx- " + Tools.ByteArrayToHexString(bytesReceived));
if ((bytesReceived[0] != 0x00) && (bytesReceived[0] != 0x80))
{
if (CR95HF_ErrorCodes.ContainsKey(bytesReceived[0]))
OnMessageEvent("NFC CR95HF error: " + CR95HF_ErrorCodes[bytesReceived[0]]);
else
OnMessageEvent("NFC CR95HF error: Unidentified");
return false;
}
}
else
{
OnMessageEvent(_SERIAL_Driver.ErrorMessage);
return false;
}
return true;
}
public bool CR95HF_RFProtocolOff()
{
byte[] bytesReceived;
if (_SERIAL_Driver.isOpen())
{
//OnMessageEvent("Tx- " + Tools.ByteArrayToHexString(CR95HF_CMD_PROTOCOL_SELECT_OFF));
_SERIAL_Driver.SendMessage(CR95HF_CMD_PROTOCOL_SELECT_OFF, CR95HF_CMD_PROTOCOL_SELECT_OFF.Length);
if (_SERIAL_Driver.GetRawData().Length == 0) return false;
bytesReceived = _SERIAL_Driver.GetRawData();
//OnMessageEvent("Rx- " + Tools.ByteArrayToHexString(bytesReceived));
if ((bytesReceived[0] != 0x00) && (bytesReceived[0] != 0x80))
{
if (CR95HF_ErrorCodes.ContainsKey(bytesReceived[0]))
OnMessageEvent("NFC CR95HF error: " + CR95HF_ErrorCodes[bytesReceived[0]]);
else
OnMessageEvent("NFC CR95HF error: Unidentified");
return false;
}
}
else
{
OnMessageEvent(_SERIAL_Driver.ErrorMessage);
return false;
}
return true;
}
public bool CR95HF_SendRecv(byte[] fromDevice, out byte[] toDevice)
{
CR95HF_CMD_SEND_RECEIVE = new List<byte>();
toDevice = null;
if (_SERIAL_Driver.isOpen())
{
CR95HF_CMD_SEND_RECEIVE.Add(0x04);//Command Code
CR95HF_CMD_SEND_RECEIVE.Add((byte)(1 + fromDevice.Length)); // This is bytes from device + 1 (because request flags byte added here)
CR95HF_CMD_SEND_RECEIVE.Add(REQUEST_FLAGS);
CR95HF_CMD_SEND_RECEIVE.AddRange(fromDevice);
//OnMessageEvent("Tx- " + Tools.ByteArrayToHexString(CR95HF_CMD_SEND_RECEIVE.ToArray()));
_SERIAL_Driver.SendMessage(CR95HF_CMD_SEND_RECEIVE.ToArray(), CR95HF_CMD_SEND_RECEIVE.Count);
if (_SERIAL_Driver.GetRawData().Length == 0) return false;
byte[] bytesReceived = _SERIAL_Driver.GetRawData();
//OnMessageEvent("Rx- " + Tools.ByteArrayToHexString(bytesReceived));
if ((bytesReceived[0] == 0x00) || (bytesReceived[0] == 0x80) || (bytesReceived[0] == 0xA0) || (bytesReceived[0] == 0xC0))
{
toDevice = new byte[bytesReceived[1]];
for (int i = 0; i < Convert.ToInt32(bytesReceived[1]); i++)
{
toDevice[i] = bytesReceived[2 + i];
}
}
else
{
if (CR95HF_ErrorCodes.ContainsKey(bytesReceived[0]))
OnMessageEvent("NFC CR95HF error: " + CR95HF_ErrorCodes[bytesReceived[0]]);
else
OnMessageEvent("NFC CR95HF error: Unidentified");
return false;
}
}
else
{
OnMessageEvent(_SERIAL_Driver.ErrorMessage);
return false;
}
return true;
}
public bool CR95HF_Echo()
{
if (_SERIAL_Driver.isOpen())
{
if (_SERIAL_Driver.SendMessage(CR95HF_CMD_ECHO, 1))
{
if (_SERIAL_Driver.GetRawData().Length == 0) return false;
byte[] bytesReceived = _SERIAL_Driver.GetRawData();
if ((bytesReceived.Length == 1) && (bytesReceived[0] == CR95HF_CMD_ECHO[0]))
return true;
}
}
else
{
OnMessageEvent(_SERIAL_Driver.ErrorMessage);
return false;
}
return false;
}
}
}
+150 -43
View File
@@ -7,6 +7,7 @@ using System.Threading;
using System.Diagnostics;
using System.IO.Ports;
using System.Timers;
using System.Runtime.CompilerServices;
//*****************************************************************************
// Copyright 2020 Sensus GmbH Ludwigshafen. All rights reserved.
@@ -22,7 +23,6 @@ namespace Sensus.iPerl.NfcHandler
private readonly byte STX = (byte) 0x02;
private readonly byte ETX = (byte) 0x03;
private readonly byte RX_ACK_RESPONSE_MSG_ID = (byte) 0xC9;
private readonly byte RX_ACK_PASSTHROUGH_MSG_ID = (byte)0xCE;
private readonly ushort[] MciPasswords = { 0x0000, 0x55AA, 0x1234, 0x97D1 };
public event DelNfc_MCI_MessageHandler MessageEvent;
@@ -286,6 +286,7 @@ namespace Sensus.iPerl.NfcHandler
byte[] valueNfcSecurityUnsignedReadResponse = { 0xD4, 0xD1, 0x97 };
MCI_ReadResponse_Info.Add(16, valueNfcSecurityUnsignedReadResponse);//NFC Security non-signed message response - while reading
}
public bool MCI_Write(StructName StName, ushort offset, byte payloadlength, byte[] inBuffer, int timeoutMs,
out byte errorCode)
{
@@ -296,33 +297,27 @@ namespace Sensus.iPerl.NfcHandler
errorCode = (byte) MCI_ErrorCodes.Success_No_error;
if (payloadlength != inBuffer.Length)
{
OnMessageEvent("Insufficient Payload !, Payload length given as: " + inBuffer.Length);
{
// Insufficient Payload length
errorCode = (byte)MCI_ErrorCodes.MCI_Error_Host_Bad_Payload_Len;
return false;
}
if (StName == StructName.Command)
{
if (MCI_Protocol.MCI_CmdCodes.ContainsKey(inBuffer[0]))
if (! MCI_Protocol.MCI_CmdCodes.ContainsKey(inBuffer[0]))
{
OnMessageEvent("Write " + MCI_Protocol.MCI_CmdCodes[inBuffer[0]]);
}
else
{
OnMessageEvent("Command: Not supported");
// Command not supported
errorCode = (byte)MCI_ErrorCodes.MCI_Error_Host_CommandNotInCmdCodeList;
return false;
}
}
else
else // not a command => should be struct
{
if (!IsValidStruct(StName))
{
errorCode = (byte)MCI_ErrorCodes.MCI_Error_Host_InvalidStructureID_CannotSendMsg;
OnMessageEvent("Write request:" + MCI_Protocol.GetMCIErrorMessage(errorCode));
return false;
}
OnMessageEvent("Write " + StructToStr(StName) + ": " + Tools.BytesToHex(inBuffer));
}
byte[] MsgId_Password = MCI_Write_Info[(int)StName];
@@ -347,12 +342,10 @@ namespace Sensus.iPerl.NfcHandler
RequestMessage.Add(crcValue[1]);
RequestMessage.Add(ETX);
OnMessageEvent("Write Request: " + Tools.BytesToHex(RequestMessage.ToArray()));
OnMessageEvent("Write " + StructToStr(StName) + "Request: " + Tools.BytesToHex(RequestMessage.ToArray()));
errorCode = MCI_TxRequest_RxResponse(RequestMessage.ToArray(), out ResponseMessage, timeoutMs);
if (errorCode != (byte)MCI_ErrorCodes.Success_No_error)
{
OnMessageEvent("WriteReq denied");
errorCode = (byte)MCI_ErrorCodes.MCI_Error_Host_WriteReq_denied;
return false;
}
//Response message received
@@ -360,33 +353,159 @@ namespace Sensus.iPerl.NfcHandler
byte[] RxCrcMeter = new byte[2];
// CRC starts at length + STX(1) + lenbyte(1) = RespMsg[1] + 2.
Array.Copy(ResponseMessage, ResponseMessage[1] + 2, RxCrcMeter, 0, 2);
OnMessageEvent(Crc.commentCRC(RxCrcMeter, RxCrcComputed));
if (!Crc.crc_do_match(RxCrcMeter, RxCrcComputed))
{
OnMessageEvent("CRC from Meter and PC do not match!");
OnMessageEvent(Crc.commentCRC(RxCrcMeter, RxCrcComputed));
errorCode = (byte) MCI_ErrorCodes.MCI_Error_Host_MeterCRCDoesNotMatch;
return false;
}
if ((ResponseMessage[0] == STX)
&& (ResponseMessage[1] == 0x07)
&& (ResponseMessage[2] == RX_ACK_PASSTHROUGH_MSG_ID || ResponseMessage[2] == RX_ACK_RESPONSE_MSG_ID)
if ((ResponseMessage[0] == STX)
&& (ResponseMessage[1] == 0x07)
&& (ResponseMessage[2] == RX_ACK_RESPONSE_MSG_ID)
&& (ResponseMessage[11] == ETX))
{
errorCode = ResponseMessage[6]; // meter error. Must be between 0..8
OnMessageEvent("Write " + StructToStr(StName) + "Request Response: " + Tools.BytesToHex(ResponseMessage));
errorCode = ResponseMessage[6]; // meter error. Must be between 0..8.
// Will be converted to errormessage string from the calling method.
if (errorCode != 0)
{
OnMessageEvent("Write Calibration: Failed with error " + Tools.ByteToHexString(errorCode));
OnMessageEvent("Write " + StructToStr(StName) + " failed. Request Response: " + Tools.BytesToHex(ResponseMessage));
return false;
}
OnMessageEvent("Write : Success");
return true;
}
OnMessageEvent("WriteReq bad device ans");
errorCode = (byte) MCI_ErrorCodes.MCI_Error_Host_WriteReq_bad_device_ans;
return false;
}
public bool MCI_Write_Read(StructName StName, ushort offset, byte payloadlength, byte[] inBuffer, out byte[] outBuffer, int timeoutMs,
out byte errorCode)
{
List<byte> RequestMessage = new List<byte>();
byte[] ResponseMessage = null;
byte[] crcValue = new byte[2];
byte RxMsgLength;
byte RxMsgId;
byte[] RxOffset = new byte[2];
byte RxPayloadlength;
byte[] RxCrcMeter = new byte[2];
outBuffer = null;
errorCode = (byte)MCI_ErrorCodes.Success_No_error;
if (payloadlength != inBuffer.Length)
{
// Insufficient Payload length
errorCode = (byte)MCI_ErrorCodes.MCI_Error_Host_Bad_Payload_Len;
return false;
}
if (StName == StructName.Command)
{
if (!MCI_Protocol.MCI_CmdCodes.ContainsKey(inBuffer[0]))
{
// Command not supported
errorCode = (byte)MCI_ErrorCodes.MCI_Error_Host_CommandNotInCmdCodeList;
return false;
}
}
else // not a command => should be struct
{
if (!IsValidStruct(StName))
{
errorCode = (byte)MCI_ErrorCodes.MCI_Error_Host_InvalidStructureID_CannotSendMsg;
return false;
}
}
byte[] MsgId_Password = MCI_Write_Info[(int)StName];
RequestMessage.Add(STX);
RequestMessage.Add(Convert.ToByte(6 + payloadlength));
RequestMessage.Add(MsgId_Password[0]);
RequestMessage.Add((byte)(offset & 0x00FF));
RequestMessage.Add((byte)((offset & 0xFF00) >> 8));
RequestMessage.Add(payloadlength);
for (int i = 0; i < payloadlength; i++) // copy Buffer -> Request Payload
{
RequestMessage.Add(inBuffer[i]);
}
RequestMessage.Add(MsgId_Password[1]);
RequestMessage.Add(MsgId_Password[2]);
// calc CRC and add to request
crcValue = Crc.calcCRCfromMessage(RequestMessage.ToArray());
RequestMessage.Add(crcValue[0]);
RequestMessage.Add(crcValue[1]);
RequestMessage.Add(ETX);
OnMessageEvent("Write " + StructToStr(StName) + "Request: " + Tools.BytesToHex(RequestMessage.ToArray()));
errorCode = MCI_TxRequest_RxResponse(RequestMessage.ToArray(), out ResponseMessage, timeoutMs);
if (errorCode != (byte)MCI_ErrorCodes.Success_No_error)
{
return false;
}
if ((ResponseMessage[0] == STX) && (ResponseMessage[11] == ETX)
&& (ResponseMessage[1] == 0x07)
&& (ResponseMessage[2] == RX_ACK_RESPONSE_MSG_ID))
{
//Ack message received, not served the read request
errorCode = ResponseMessage[6]; // forward error message from meter
OnMessageEvent("Read " + StructToStr(StName) + ": Failed with error "
+ Tools.ByteToHexString(errorCode));
return false;
}
//Response message received
RxMsgLength = ResponseMessage[1];
RxMsgId = ResponseMessage[2];
// RxOffset[0] = ResponseMessage[3];
// RxOffset[1] = ResponseMessage[4];
RxPayloadlength = ResponseMessage[5];
// RxPassword[0] = ResponseMessage[6 + RxPayloadlength];
// RxPassword[1] = ResponseMessage[7 + RxPayloadlength];
RxCrcMeter[0] = ResponseMessage[8 + RxPayloadlength];
RxCrcMeter[1] = ResponseMessage[9 + RxPayloadlength];
byte[] RxCrcComputed = Crc.calcCRCfromMessage(ResponseMessage);
// OnMessageEvent(Crc.commentCRC(RxCrcMeter, RxCrcComputed));
if (!Crc.crc_do_match(RxCrcMeter, RxCrcComputed))
{
errorCode = (byte)MCI_ErrorCodes.MCI_Error_Host_MeterCRCDoesNotMatch;
return false;
}
//TODO, verify received password matches with expected password or not?
if (!((ResponseMessage[0] == STX) && (ResponseMessage[10 + RxPayloadlength] == ETX)
&& ((ResponseMessage[2] & 0x3F) == (MsgId_Password[0] & 0x3F))))
{
errorCode = (byte)MCI_ErrorCodes.MCI_Error_Host_ReadReqBadResponseStructure;
return false;
}
outBuffer = new byte[RxPayloadlength];
for (int i = 0; i < RxPayloadlength; i++)
{
outBuffer[i] = (ResponseMessage[6 + i]);
}
if (IsValidStruct(StName))
{
OnMessageEvent("Read " + StructToStr(StName) + ": " + Tools.BytesToHex(outBuffer)
+ " Success");
}
else
{
OnMessageEvent("Read Failed! Unknown MCI ID: " + Convert.ToByte(StName));
errorCode = (byte)MCI_ErrorCodes.MCI_Error_Host_Bad_MCI_ID;
return false;
}
errorCode = (byte)0x00; //Success, No error
return true;
}
public bool MCI_Read(StructName StName, ushort offset, byte payloadlength, int timeoutMs,
out byte[] outBuffer, out byte errorCode)
{
@@ -409,9 +528,8 @@ namespace Sensus.iPerl.NfcHandler
{
errorCode = (byte)MCI_ErrorCodes.MCI_Error_Host_InvalidStructureID_CannotSendMsg;
OnMessageEvent("Read request:" + MCI_Protocol.GetMCIErrorMessage(errorCode));
return false;
return false;
}
OnMessageEvent("Read " + StructToStr(StName));
RequestMessage.Add(STX);
RequestMessage.Add(0x06);
@@ -430,12 +548,11 @@ namespace Sensus.iPerl.NfcHandler
errorCode = MCI_TxRequest_RxResponse(RequestMessage.ToArray(), out ResponseMessage, timeoutMs);
if (errorCode != (byte) MCI_ErrorCodes.Success_No_error)
{
OnMessageEvent("Read Request:" + MCI_Protocol.GetMCIErrorMessage(errorCode));
return false;
}
if ((ResponseMessage[0] == STX) && (ResponseMessage[11] == ETX)
&& (ResponseMessage[1] == 0x07)
&& (ResponseMessage[2] == RX_ACK_PASSTHROUGH_MSG_ID || ResponseMessage[2] == RX_ACK_RESPONSE_MSG_ID) )
&& (ResponseMessage[2] == RX_ACK_RESPONSE_MSG_ID))
{
//Ack message received, not served the read request
errorCode = ResponseMessage[6]; // forward error message from meter
@@ -456,7 +573,7 @@ namespace Sensus.iPerl.NfcHandler
byte[] RxCrcComputed = Crc.calcCRCfromMessage(ResponseMessage);
OnMessageEvent(Crc.commentCRC(RxCrcMeter, RxCrcComputed));
// OnMessageEvent(Crc.commentCRC(RxCrcMeter, RxCrcComputed));
if (!Crc.crc_do_match(RxCrcMeter, RxCrcComputed))
{
errorCode = (byte) MCI_ErrorCodes.MCI_Error_Host_MeterCRCDoesNotMatch;
@@ -476,7 +593,6 @@ namespace Sensus.iPerl.NfcHandler
{
outBuffer[i] = (ResponseMessage[6 + i]);
}
OnMessageEvent("Read Request Response: " + Tools.BytesToHex(ResponseMessage));
if (IsValidStruct(StName))
@@ -505,7 +621,6 @@ namespace Sensus.iPerl.NfcHandler
if (!_ST25DV_Device.ST25DV_ReadMailboxControlReg(out MB_Ctrl_Reg_Value))
{
OnMessageEvent("NFC DLL Error: MB CTRL Reg read (1) failed");
MCI_CycleResponseMsgTimeoutFlag = false;
stopReqResCycleTimeoutTimer();
return (byte) MCI_ErrorCodes.MCI_Error_Host_MB_CTRL_Reg_Read1;
@@ -513,10 +628,10 @@ namespace Sensus.iPerl.NfcHandler
//Mailbox enable/disable check, proceed further only if enabled
if ((MB_Ctrl_Reg_Value & 0x01) == 0x00)
{
OnMessageEvent("NFC DLL Error: MB feature (1) disabled");
MCI_CycleResponseMsgTimeoutFlag = false;
stopReqResCycleTimeoutTimer();
return (byte)MCI_ErrorCodes.MCI_Error_Host_MB_disabled1;
stopReqResCycleTimeoutTimer();
OnMessageEvent(">> REMARK: Check if Metorlogy firmware-version is at least: 5.1.24 <<");
return (byte)MCI_ErrorCodes.MCI_Error_Host_MB_disabled1;
}
//Checking iPERL previous message is in mailbox or not, if present then read it and return failure
if ((MB_Ctrl_Reg_Value & 0x02) == 0x02)
@@ -525,7 +640,6 @@ namespace Sensus.iPerl.NfcHandler
OnMessageEvent("NFC DLL Error: Previous message not read, reading now !");
if (!_ST25DV_Device.ST25DV_ReadMailboxMessageLength(out MB_LEN_Dyn_Register))
{
OnMessageEvent("NFC DLL Error: MB LEN Reg read (1) failed");
returnError = (byte)MCI_ErrorCodes.MCI_Error_Host_MB_LEN_Reg_read1;
}
else
@@ -533,7 +647,6 @@ namespace Sensus.iPerl.NfcHandler
OnMessageEvent("NFC DLL Error: Previous message length " + MB_LEN_Dyn_Register);
if (!_ST25DV_Device.ST25DV_ReadMessage(MB_LEN_Dyn_Register, out responseMsg))
{
OnMessageEvent("NFC DLL Error: MB message read (1) failed");
returnError = (byte)MCI_ErrorCodes.MCI_Error_Host_MB_msg_read1;
}
else
@@ -551,7 +664,7 @@ namespace Sensus.iPerl.NfcHandler
//Checking previous app message is in mailbox or not, if present then return failure !
if ((MB_Ctrl_Reg_Value & 0x04) == 0x04)
{
OnMessageEvent("NFC DLL Error: Previous sent request is not read by iPERL. So, present request will not be sent, retry again !");
// Previous sent request is not read by iPERL
MCI_CycleResponseMsgTimeoutFlag = false;
stopReqResCycleTimeoutTimer();
return (byte)MCI_ErrorCodes.MCI_Error_Host_req_not_read_by_iperl;
@@ -563,7 +676,6 @@ namespace Sensus.iPerl.NfcHandler
{
if (!_ST25DV_Device.ST25DV_ReadMailboxControlReg(out MB_Ctrl_Reg_Value))
{
OnMessageEvent("NFC DLL Error: MB CTRL Reg read (2) failed");
MCI_CycleResponseMsgTimeoutFlag = false;
stopReqResCycleTimeoutTimer();
return (byte)MCI_ErrorCodes.MCI_Error_Host_MB_CTRL_Reg_Read2;
@@ -571,7 +683,6 @@ namespace Sensus.iPerl.NfcHandler
//Mailbox enable/disable check, proceed further only if enabled
if ((MB_Ctrl_Reg_Value & 0x01) == 0x00)
{
OnMessageEvent("NFC DLL Error: MB feature (2) disabled");
MCI_CycleResponseMsgTimeoutFlag = false;
stopReqResCycleTimeoutTimer();
return (byte)MCI_ErrorCodes.MCI_Error_Host_MB_disabled2;
@@ -582,7 +693,6 @@ namespace Sensus.iPerl.NfcHandler
{
if (!_ST25DV_Device.ST25DV_ReadMailboxMessageLength(out MB_LEN_Dyn_Register))
{
OnMessageEvent("NFC DLL Error: MB LEN Reg read (2) failed");
MCI_CycleResponseMsgTimeoutFlag = false;
stopReqResCycleTimeoutTimer();
return (byte)MCI_ErrorCodes.MCI_Error_Host_MB_LEN_Reg_read2;
@@ -591,7 +701,6 @@ namespace Sensus.iPerl.NfcHandler
{
if (!_ST25DV_Device.ST25DV_ReadMessage(MB_LEN_Dyn_Register, out responseMsg))
{
OnMessageEvent("NFC DLL Error: MB message read (2) failed");
MCI_CycleResponseMsgTimeoutFlag = false;
stopReqResCycleTimeoutTimer();
return (byte)MCI_ErrorCodes.MCI_Error_Host_MB_msg_read2;
@@ -609,7 +718,6 @@ namespace Sensus.iPerl.NfcHandler
//Checking timeout occured or not
if(MCI_CycleResponseMsgTimeoutFlag)
{
OnMessageEvent("NFC DLL Error: Timeout");
MCI_CycleResponseMsgTimeoutFlag = false;
stopReqResCycleTimeoutTimer();
return (byte)MCI_ErrorCodes.MCI_Error_Host_Timeout;
@@ -618,7 +726,6 @@ namespace Sensus.iPerl.NfcHandler
}
else
{
OnMessageEvent("NFC DLL Error: MB Msg write failed");
MCI_CycleResponseMsgTimeoutFlag = false;
stopReqResCycleTimeoutTimer();
return (byte)MCI_ErrorCodes.MCI_Error_Host_msg_write;
+114 -125
View File
@@ -1,7 +1,8 @@
using System;
using System.IO.Ports;
using System.Diagnostics;
using System.Text;
using System.Threading;
//*****************************************************************************
// Copyright 2020 Sensus GmbH Ludwigshafen. All rights reserved.
@@ -12,6 +13,8 @@ namespace Sensus.iPerl.NfcHandler
{
public sealed class NfcDataHandler
{
private string _ComPort = "";
private readonly byte[] readCommand = { 0x80, 0x08, 0x00, 0x03, 0x00, 0x00 };
public SERIAL_Driver _SERIAL_Driver;
public SERIAL_Driver _SERIAL_Driver_Head_Config;
@@ -27,8 +30,6 @@ namespace Sensus.iPerl.NfcHandler
public event DelNfcMessageHandler MessageEvent;
private string _ComPort = "";
public NfcDataHandler()
{
_SERIAL_Driver = new SERIAL_Driver();
@@ -37,14 +38,14 @@ namespace Sensus.iPerl.NfcHandler
_ST25DV_Device = new ST25DV_Device(_CR95HF_Reader);
_MCI_Protocol = new MCI_Protocol(_ST25DV_Device);
_NFCHead_Config = new NFCHeadConfig(_SERIAL_Driver_Head_Config);
LastErrorCode = 0;
LastErrorCode = 0;
}
public bool OpenConnection(string comport, int baudrate, int databits, Parity parity, StopBits stopbits)
{
_ComPort = comport;
bool isopen = _SERIAL_Driver.OpenConnection(comport, baudrate, databits, parity, stopbits);
if(!isopen)OnMessageEvent(_SERIAL_Driver.ErrorMessage);
if (!isopen) OnMessageEvent(_SERIAL_Driver.ErrorMessage);
return isopen;
}
@@ -75,7 +76,7 @@ namespace Sensus.iPerl.NfcHandler
OnMessageEvent(comport + "......... Already in use ");
return false;
}
bool isopen = _SERIAL_Driver_Head_Config.OpenConnection(comport, 9600, 8, Parity.None, StopBits.Two);
OnMessageEvent(_SERIAL_Driver_Head_Config.ErrorMessage);
return isopen;
@@ -140,7 +141,7 @@ namespace Sensus.iPerl.NfcHandler
public bool ConnectDevice()
{
byte[] responseData;
if (_CR95HF_Reader.CR95HF_RFProtocolOn())
{
if (GetSystemInfo())
@@ -188,7 +189,7 @@ namespace Sensus.iPerl.NfcHandler
OnMessageEvent(ex.Message);
}
return false;
}
}
public bool ST25DV_ReadSingleBlock(byte blockNumber, out byte[] outBuffer)
{
@@ -256,18 +257,17 @@ namespace Sensus.iPerl.NfcHandler
if (!worked)
{
SetLastErrorMesage();
ST25DV_MailboxCommStop();
return false;
}
return ST25DV_MailboxCommStop();
return true;
}
return false;
}
// This function-header is needed for calls to the DLL without need for using enums.
// In python 3.11 the module pythonnet (v3.x) does not support casting 'int' to 'enum' aynmore,
// so this workaround is needed.
public bool MCI_Write_pythonwrapper_enum(int STIndex, ushort offset, byte payloadlength, byte[] payload, int timeoutMs)
// This function-header is needed for calls to the DLL without need for using enums.
// In python 3.11 the module pythonnet (v3.x) does not support casting 'int' to 'enum' aynmore,
// so this workaround is needed.
public bool MCI_Write_pythonwrapper_enum(int STIndex, ushort offset, byte payloadlength, byte[] payload, int timeoutMs)
{
return MCI_Write((MCI_Protocol.StructName)STIndex, offset, payloadlength, payload, timeoutMs);
}
@@ -284,140 +284,74 @@ namespace Sensus.iPerl.NfcHandler
if (!ans)
{
SetLastErrorMesage();
ST25DV_MailboxCommStop();
return false;
}
return ST25DV_MailboxCommStop();
return true;
}
return false;
}
public bool MCI_Read(byte msgId, ushort offset, byte payloadlength, int timeoutMs)
public bool MCI_Write_Read(MCI_Protocol.StructName StName, ushort offset, byte payloadlength, byte[] payload, int timeoutMs)
{
LastErrorMessage = string.Empty;
LastData = null;
byte[] response;
byte errorCode = 0;
if (ST25DV_MailboxCommStart())
{
bool ans = _MCI_Protocol.MCI_Read((MCI_Protocol.StructName) msgId, offset, payloadlength, timeoutMs,
out response, out errorCode);
bool ans = _MCI_Protocol.MCI_Write_Read(StName, offset, payloadlength, payload, out response, timeoutMs, out errorCode);
LastErrorCode = errorCode;
LastData = response;
if (!ans)
{
SetLastErrorMesage();
ST25DV_MailboxCommStop();
return false;
}
return ST25DV_MailboxCommStop();
}
return false;
}
public bool MCI_Write(byte msgId, ushort offset, byte payloadlength, byte[] payload, int timeoutMs)
{
LastErrorMessage = string.Empty;
LastData = null;
byte errorCode = 0;
if (ST25DV_MailboxCommStart())
{
bool ans = _MCI_Protocol.MCI_Write((MCI_Protocol.StructName) msgId, offset, payloadlength, payload,
timeoutMs, out errorCode);
LastErrorCode = errorCode;
if (!ans)
{
SetLastErrorMesage();
ST25DV_MailboxCommStop();
return false;
}
return ST25DV_MailboxCommStop();
return true;
}
return false;
}
private bool ST25DV_MailboxCommStart()
{
bool success = false;
byte[] EepromBlockRead = { 0, 0, 0, 0 };
byte[] EepromBlockWrite = { 0, 0, 0, 0 };
//Byte-2 in block-2 represent the EEPROM I2C interface status ->
//0xA5-EEPROM I2C Interface Idle, 0x5A-EEPROM I2C Interface Active
success = _ST25DV_Device.ST25DV_ReadSingleBlock(2, out EepromBlockRead, false);
if (success)
// wake up the ST25DV by setting the GPO pin to output a pulse -> INT on Metro (set highest bit to one -> causes a pulse on GPO)
if (_ST25DV_Device.ST25DV_WriteGPOManageCommand(_ST25DV_Device.GPO_MANAGE_SET_PULSE, false))
{
if (EepromBlockRead[1] == 0xA5) //0xA5-EEPROM I2C Interface Idle
{
//Byte-1 in block-64 represent the Mailbox RF interface status ->
//0xA5-Mailbox RF Interface Idle, 0x5A-Mailbox RF Interface Active
EepromBlockWrite[0] = 0x5A; //Raising Mailbox RF interface Active flag to avoid collisions with host interface
success = _ST25DV_Device.ST25DV_WriteSingleBlock(64, EepromBlockWrite, false);
if (success)
{
//Sets 0x01 (MB_EN) in the register (MB_CTRL_Dyn) with address 0x0D
if (_ST25DV_Device.ST25DV_WriteDynamicConfiguration(0x0D, 0x01, false))
{
return true; //With this we proceed for mailbox communication with ST25
}
else
{
LastErrorCode = 0x08; //MCI Error: Unidentified
LastErrorMessage = "MB_CTRL_Dyn writing failed(ST25DV_MailboxCommStart), try again";
return false;
}
}
else
{
LastErrorCode = 0x08; //MCI Error: Unidentified
LastErrorMessage = "Mailbox RF interface status writing failed(ST25DV_MailboxCommStart), try again";
return false;
}
}
else
{
LastErrorCode = 0x08; //MCI Error: Unidentified
LastErrorMessage = "EEPROM interface busy(ST25DV_MailboxCommStart), try again";
return false;
}
Thread.Sleep(10); // wait 10ms to give metro some time
byte MB_Ctrl_Reg_Value = 0x00;
for (int i = 0; i < 20; i++) // do 20 retries max (20 times 100ms = 2sec, which should be more than enough)
{
if (_ST25DV_Device.ST25DV_ReadMailboxControlReg(out MB_Ctrl_Reg_Value))
{
if ((MB_Ctrl_Reg_Value & 0x01) == 0x01)
{
return true; //With this we proceed for mailbox communication with ST25
}
else
{
Thread.Sleep(100); // wait 100ms, then try again
LastErrorMessage = "Mailbox was not activated by Firmware (ST25DV_MailboxCommStart), try again";
}
}
else
{
Thread.Sleep(100); // wait 100ms, then try again
LastErrorMessage = "Mailbox state could not be read (ST25DV_MailboxCommStart), try again";
}
}
LastErrorCode = 0x08; //MCI Error: Unidentified
OnMessageEvent(">> REMARK: Check if Metorlogy firmware-version is at least: 5.1.24 <<");
return false;
}
else
{
LastErrorCode = 0x08; //MCI Error: Unidentified
LastErrorMessage = "EEPROM interface status reading failed(ST25DV_MailboxCommStart), try again";
LastErrorMessage = "GPO config writing failed(ST25DV_MailboxCommStart), try again";
return false;
}
}
private bool ST25DV_MailboxCommStop()
{
bool success = false;
byte[] EepromBlockWrite = { 0, 0, 0, 0 };
//Sets 0x00 (MB_EN) in the register (MB_CTRL_Dyn) with address 0x0D
if (_ST25DV_Device.ST25DV_WriteDynamicConfiguration(0x0D, 0x00, false))
{
//Byte-1 in block-64 represent the Mailbox RF interface status ->
//0xA5-Mailbox RF Interface Idle, 0x5A-Mailbox RF Interface Active
EepromBlockWrite[0] = 0xA5; //Raising Mailbox RF interface Idle flag to avoid collisions with host interface
success = _ST25DV_Device.ST25DV_WriteSingleBlock(64, EepromBlockWrite, false);
if (success)
{
return true; //With this we proceed for interpreting the communication happened with ST25
}
else
{
LastErrorCode = 0x08; //MCI Error: Unidentified
LastErrorMessage = "Mailbox RF interface status writing failed(ST25DV_MailboxCommStop), try again";
return false;
}
}
else
{
LastErrorCode = 0x08; //MCI Error: Unidentified
LastErrorMessage = "MB_CTRL_Dyn writing failed(ST25DV_MailboxCommStop), try again";
return false;
}
}
private void SetLastErrorMesage()
{
@@ -430,7 +364,7 @@ namespace Sensus.iPerl.NfcHandler
LastErrorMessage = "MCI Error: The Errorcode '" + LastErrorCode as string +
"' couldn't be converted to string with the enum MCI_ErrorCodes!";
}
}
public bool NFCHeadConfig_PulseLedOutputEnable()
@@ -480,7 +414,7 @@ namespace Sensus.iPerl.NfcHandler
try
{
if ( (!MCI_Write(MCI_Protocol.StructName.NfcSecurity, offset, payloadLength, payload, timeoutMs)) || (LastErrorCode != 0x00))
if ((!MCI_Write(MCI_Protocol.StructName.NfcSecurity, offset, payloadLength, payload, timeoutMs)) || (LastErrorCode != 0x00))
{
return false;
}
@@ -492,11 +426,68 @@ namespace Sensus.iPerl.NfcHandler
return true; // true - success, false - failed
}
public string NFCSecurity_Read_EndpointId(int timeoutMs)
{
string result = string.Empty;
byte[] payload = readCommand;
byte payloadLength = Convert.ToByte(payload.Length);
ushort offset = 0;
try
{
if ((!MCI_Write_Read(MCI_Protocol.StructName.NfcSecurity, offset, payloadLength, payload, timeoutMs)) || (LastErrorCode != 0x00))
{
return string.Empty;
}
}
catch (Exception ex)
{
OnMessageEvent(ex.Message);
return string.Empty;
}
//Check response header
if (LastData[0] != 0x05 || LastData[1] != 0x00)
{
LastErrorMessage = "Wrong response header";
return string.Empty;
}
//Check length byte
if (LastData[2] == 0x00)
{
LastErrorMessage = "Response length is 0";
return string.Empty;
}
//Check length of message
int lengthMessage = LastData[2] + 3; // two header bytes and one length byte
if (LastData.Length != lengthMessage)
{
LastErrorMessage = "Response length is wrong";
return string.Empty;
}
//Check identifier for information
if (LastData[3] != 0x00 || LastData[4] != 0x00)
{
LastErrorMessage = "Wrong identifier";
return string.Empty;
}
int lengthEndpointId = LastData[2] - 2; //Identifier bytes
byte[] id = new byte[lengthEndpointId];
Array.Copy(LastData, 5, id, 0, lengthEndpointId);
result = Encoding.ASCII.GetString(id);
return result;
}
public byte NFCSecurity_ReadPrivilegeLevel(int timeoutMs)
{
ushort offset = 0;
byte payloadLength = 1;
byte payload = 4;
byte payload = 4;
try
{
if ((!MCI_Read(MCI_Protocol.StructName.NfcSecurity, offset, payloadLength, timeoutMs)) || (LastErrorCode != 0x00))
@@ -520,7 +511,7 @@ namespace Sensus.iPerl.NfcHandler
{
ushort offset = 0;
byte payloadLength = 1;
byte [] payload = { 0x23 }; // 0x23 - Command code for 'NFC Security reset access level'
byte[] payload = { 0x23 }; // 0x23 - Command code for 'NFC Security reset access level'
try
{
@@ -536,13 +527,11 @@ namespace Sensus.iPerl.NfcHandler
return true; // true - success, false - failed
}
public string GetDllVersion()
{
System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
string str = "NfcS5 DLL v" + fvi.FileVersion;
return str.Remove(str.Length - 2); // only show x.y.z version, hide 4th number
}
public string GetDllVersion()
{
Version dll_version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
return "NfcS5 DLL v" + String.Format("{0}.{1}.{2}", dll_version.Major, dll_version.Minor, dll_version.Build); //, dll_version.MajorRevision);
}
#region Message Event
private void OnMessageEvent(string message)
+41 -18
View File
@@ -22,8 +22,10 @@ namespace Sensus.iPerl.NfcHandler
private byte[] ST25DV_CMD_WRITE_DYNAMIC_CONFIG = { 0xAE, 0x02, 0x00, 0x00 }; //Command code, IC Mfg Code, Register address, register value to be written
private readonly byte[] ST25DV_CMD_READ_MAILBOX_CONTROL_REG = { 0xAD, 0x02, 0x0D }; //Command code, IC Mfg Code, MB_CTRL_Dyn Register address
private readonly byte[] ST25DV_CMD_READ_MAILBOX_MESSAGE_LENGTH = { 0xAB, 0x02 }; //Command code, IC Mfg Code
private byte[] ST25DV_CMD_READ_MESSAGE = { 0xAC, 0x02, 0x00, 0x00 }; //Command code, IC Mfg Code, Mailbox pointer(mostly this is 0), NumberofBytesToRead (this will be received from caller)
private byte[] ST25DV_CMD_READ_MESSAGE = { 0xAC, 0x02, 0x00, 0x00 }; //Command code, IC Mfg Code, Mailbox pointer(mostly this is 0), NumberofBytesToRead (this will be received from caller)
private byte[] ST25DV_CMD_MANAGE_GPO = { 0xA9, 0x02, 0x00 }; //Command code, IC Mfg Code, GPO value
public readonly byte GPO_MANAGE_SET_PULSE = 0x80; // Command code to set a pulse on the GPO pin (if enabled by FW in the Meter)
private CR95HF_Reader _CR95HF_Reader;
private System.Timers.Timer _CycleTimeoutTimer = new System.Timers.Timer();
@@ -42,8 +44,8 @@ namespace Sensus.iPerl.NfcHandler
{0x15 , "The specified block is protected in read" }
};
public event DelNfc_ST25DV_MessageHandler MessageEvent;
public event DelNfc_ST25DV_MessageHandler MessageEvent;
public ST25DV_Device(CR95HF_Reader CR95HFReader)
{
_CR95HF_Reader = CR95HFReader;
@@ -265,12 +267,39 @@ namespace Sensus.iPerl.NfcHandler
return false;
}
public bool ST25DV_WriteGPOManageCommand(byte regValue, bool logEnabled)
{
byte[] response = null;
ST25DV_CMD_MANAGE_GPO[2] = regValue;
if (_CR95HF_Reader.CR95HF_SendRecv(ST25DV_CMD_MANAGE_GPO, out response))
{
//Success - ResponseFlags = 0x00, success
//Error - ResponseFlags = 0x01, 1 byte error code
if (response[0] == 0x00)
{
if (logEnabled)
{
OnMessageEvent("Write GPO Manage: Success");
}
return true;
}
else
{
if ((response[0] == 0x01) && (ST25DV_ErrorCodes.ContainsKey(response[1])))
OnMessageEvent("Write GPO Manage: Failed with ST25DV error - " + ST25DV_ErrorCodes[response[1]]);
}
}
OnMessageEvent("Write GPO Manage: Failed with ST25DV Unidentified error");
return false;
}
public bool ST25DV_WriteDynamicConfiguration(byte regAddress, byte regValue, bool logEnabled)
{
byte[] response = null;
byte[] response = null;
ST25DV_CMD_WRITE_DYNAMIC_CONFIG[2] = regAddress;
ST25DV_CMD_WRITE_DYNAMIC_CONFIG[3] = regValue;
ST25DV_CMD_WRITE_DYNAMIC_CONFIG[3] = regValue;
if (_CR95HF_Reader.CR95HF_SendRecv(ST25DV_CMD_WRITE_DYNAMIC_CONFIG, out response))
{
//Success - ResponseFlags = 0x00, success
@@ -365,14 +394,11 @@ namespace Sensus.iPerl.NfcHandler
{
outBuffer[i] = response[1 + i];
}
//OnMessageEvent("Read Message: " + Tools.ByteArrayToHexString(outBuffer));
OnMessageEvent("Read Message: " + Tools.BytesToHex(outBuffer));
return true;
}
else
{
if ((response[0] == 0x01) && (ST25DV_ErrorCodes.ContainsKey(response[1])))
OnMessageEvent("Read Message Failed: With ST25DV error - " + ST25DV_ErrorCodes[response[1]]);
}
if ((response[0] == 0x01) && ST25DV_ErrorCodes.ContainsKey(response[1]))
OnMessageEvent("Read Message Failed: With ST25DV error - " + ST25DV_ErrorCodes[response[1]]);
}
OnMessageEvent("Read Message Failed: With ST25DV Unidentified error");
return false;
@@ -397,11 +423,8 @@ namespace Sensus.iPerl.NfcHandler
//OnMessageEvent("Write Message: " + Tools.ByteArrayToHexString(inBuffer));
return true;
}
else
{
if ((response[0] == 0x01) && (ST25DV_ErrorCodes.ContainsKey(response[1])))
OnMessageEvent("Write Message Failed: With ST25DV error - " + ST25DV_ErrorCodes[response[1]]);
}
if ((response[0] == 0x01) && ST25DV_ErrorCodes.ContainsKey(response[1]))
OnMessageEvent("Write Message Failed: With ST25DV error - " + ST25DV_ErrorCodes[response[1]]);
}
OnMessageEvent("Write Message Failed: With ST25DV Unidentified error");
return false;
+38 -2
View File
@@ -11,13 +11,14 @@
<AssemblyName>NfcS5_DLL</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DefineConstants>DEBUG;TRACE;IPERL</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
@@ -25,13 +26,44 @@
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<DefineConstants>TRACE;IPERL;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Antlr3.Runtime, Version=3.5.0.2, Culture=neutral, PublicKeyToken=eb42632606e9261f, processorArchitecture=MSIL">
<HintPath>..\tbf\packages\Antlr3.Runtime.3.5.1\lib\net40-client\Antlr3.Runtime.dll</HintPath>
</Reference>
<Reference Include="FluentNHibernate, Version=3.4.0.0, Culture=neutral, PublicKeyToken=8aa435e3cb308880, processorArchitecture=MSIL">
<HintPath>..\tbf\packages\FluentNHibernate.3.4.0\lib\net461\FluentNHibernate.dll</HintPath>
</Reference>
<Reference Include="Iesi.Collections, Version=4.0.0.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4, processorArchitecture=MSIL">
<HintPath>..\tbf\packages\Iesi.Collections.4.0.4\lib\net461\Iesi.Collections.dll</HintPath>
</Reference>
<Reference Include="log4net, Version=3.0.4.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\tbf\packages\log4net.3.0.4\lib\net462\log4net.dll</HintPath>
</Reference>
<Reference Include="Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\tbf\packages\VisualBasic.PowerPacks.Vs.1.0.0\lib\Microsoft.VisualBasic.dll</HintPath>
</Reference>
<Reference Include="Microsoft.VisualBasic.PowerPacks.Vs, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\tbf\packages\VisualBasic.PowerPacks.Vs.1.0.0\lib\Microsoft.VisualBasic.PowerPacks.Vs.dll</HintPath>
</Reference>
<Reference Include="NHibernate, Version=5.5.0.0, Culture=neutral, PublicKeyToken=aa95f207798dfdb4, processorArchitecture=MSIL">
<HintPath>..\tbf\packages\NHibernate.5.5.2\lib\net461\NHibernate.dll</HintPath>
</Reference>
<Reference Include="Remotion.Linq, Version=2.2.0.0, Culture=neutral, PublicKeyToken=fee00910d6e5f53b, processorArchitecture=MSIL">
<HintPath>..\tbf\packages\Remotion.Linq.2.2.0\lib\net45\Remotion.Linq.dll</HintPath>
</Reference>
<Reference Include="Remotion.Linq.EagerFetching, Version=2.2.0.0, Culture=neutral, PublicKeyToken=fee00910d6e5f53b, processorArchitecture=MSIL">
<HintPath>..\tbf\packages\Remotion.Linq.EagerFetching.2.2.0\lib\net45\Remotion.Linq.EagerFetching.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.Transactions" />
<Reference Include="System.Web" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
@@ -50,6 +82,10 @@
<Compile Include="NfcHandler\Tools.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
+3 -3
View File
@@ -10,7 +10,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("NfcS5_DLL")]
[assembly: AssemblyCopyright("Copyright © 2022")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.14.0.0")]
[assembly: AssemblyFileVersion("1.14.0.0")]
[assembly: AssemblyVersion("1.18.0.0")]
[assembly: AssemblyFileVersion("1.18.0.0")]
+11
View File
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="FluentNHibernate" version="3.4.0" targetFramework="net472" />
<package id="Iesi.Collections" version="4.0.4" targetFramework="net472" />
<package id="NHibernate" version="5.5.2" targetFramework="net472" />
<package id="Antlr3.Runtime" version="3.5.1" targetFramework="net472" />
<package id="Remotion.Linq" version="2.2.0" targetFramework="net472" />
<package id="Remotion.Linq.EagerFetching" version="2.2.0" targetFramework="net472" />
<package id="VisualBasic.PowerPacks.Vs" version="1.0.0" targetFramework="net472" />
<package id="log4net" version="3.0.4" targetFramework="net472" />
</packages>