Я пытался установить связь со смарт-картой EMV на оборудовании для чтения / записи MCR200 через последовательный порт с помощью команд APDU, но все еще безуспешно. Я не получаю и ответа. Вот что я пробовал до сих пор. По крайней мере, я хочу начать с получения ATR карты, прежде чем приступить к чтению и записи записей на смарт-карту.
namespace JappaSmartCard
{
public partial class BankWrite : Form
{
public SerialPort port = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
public long bytesRead;
public byte[] buffer;
List<byte> bBuffer = new List<byte>();
string sBuffer = String.Empty;
private long SendLen, RecvLen;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 262)]
private byte[] SendBuff;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 262)]
private byte[] RecvBuff;
private const int INVALID_SW1SW2 = -450;
public BankWrite()
{
InitializeComponent();
port.Handshake = Handshake.None;
port.Encoding = Encoding.ASCII;
port.ReceivedBytesThreshold = 1;
//port.ReadTimeout = 5000;
//port.WriteTimeout = 5000;
initMenu();
// Attach a method to be called when there
// is data waiting in the port's buffer
port.DataReceived += new SerialDataReceivedEventHandler(verifyChv);
}
private void BankWrite_Load(object sender, EventArgs e)
{
pbProgress.Visible = false;
}
private void initMenu()
{
pbProgress.Visible = false;
btnWrite.Enabled = false;
btnConnect.Enabled = false;
btnRead.Enabled = false;
btnSave.Enabled = false;
btnUSB.Enabled = false;
btnFormat.Enabled = false;
btnError.Enabled = false;
btnDuplicate.Enabled = false;
gbSelectHardware.Enabled = false;
gbDetails.Enabled = false;
gbTrack1.Enabled = false;
gbTrack2.Enabled = false;
gbTrack3.Enabled = false;
txtAccountNo.Text = "";
txtFirstName.Text = "";
txtLastName.Text = "";
txtPin.Text = "";
rtbInfo.Text = "";
rtbTrack1.Text = "";
rtbTrack2.Text = "";
rtbTrack3.Text = "";
ckbARC.Checked = false;
ckbARQC.Checked = false;
ckbDDA.Checked = false;
}
private void EnableConnectButton()
{
btnInitialize.Enabled = false;
gbSelectHardware.Enabled = true;
btnConnect.Enabled = true;
}
private void ClearBuffers()
{
}
private void DisplayOut(int mType, long msgCode, string PrintText)
{
switch (mType)
{
case 0: // Notifications only
{
rtbInfo.SelectionColor = Color.Blue;
break;
}
case 1: // PC/SC Error Messages
{
rtbInfo.SelectionColor = Color.Red;
PrintText = Card.GetScardErrMsg(bytesRead);
break;
}
case 2: // Input APDU command
{
rtbInfo.SelectionColor = Color.Black;
PrintText = "< " + PrintText;
break;
}
case 3: // Output data
{
rtbInfo.SelectionColor = Color.Green;
PrintText = "> " + PrintText;
break;
}
case 4: // Notifications on red font
{
rtbInfo.SelectionColor = Color.Maroon;
break;
}
}
rtbInfo.SelectedText = PrintText + "\r\n";
rtbInfo.SelectionStart = rtbInfo.TextLength;
rtbInfo.SelectionColor = Color.Black;
}
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
// Show all the incoming data in the port's buffer
rtbInfo.Invoke(new EventHandler(delegate { rtbInfo.Text += port.ReadExisting(); }));
// Use either the binary OR the string technique (but not both)
// Buffer and process binary data
while (port.BytesToRead > 0)
bBuffer.Add((byte)port.ReadByte());
ProcessBuffer(bBuffer);
// Buffer string data
sBuffer += port.ReadExisting();
ProcessBuffer(sBuffer);
}
private void ProcessBuffer(string sBuffer)
{
}
private void ProcessBuffer(List<byte> bBuffer)
{
}
private void btnQuit_Click(object sender, EventArgs e)
{
//Application.ExitThread();
port.Close();
this.Hide();
}
private void btnInitialize_Click(object sender, EventArgs e)
{
//Get all the ports attached
pbProgress.Visible = true;
pbProgress.Maximum = SerialPort.GetPortNames().Length;
pbProgress.Step = 1;
foreach (string s in SerialPort.GetPortNames())
{
cboReaders.Items.Add(s);
pbProgress.PerformStep();
Console.WriteLine(s);
}
cboReaders.Text = "COM1";
port = new SerialPort(cboReaders.Text,9600, Parity.None, 8, StopBits.One);
port.Handshake = Handshake.None;
port.Encoding = Encoding.ASCII;
port.ReceivedBytesThreshold = 1;
EnableConnectButton();
}
[STAThread]
private void btnConnect_Click(object sender, EventArgs e)
{
if (!port.IsOpen)
port.Open();
bytesRead = 0;
//close All open thread
//Application.ExitThread();
// Enter an application loop to keep this thread alive
//Application.Run();
pbProgress.Visible = false;
btnWrite.Enabled = true;
btnConnect.Enabled = false;
btnRead.Enabled = true;
btnSave.Enabled = false;
btnUSB.Enabled = false;
btnFormat.Enabled = true;
// Check if PIN is correct
port.Write(new byte[] { 0x03, 0x20, 0x00, 0x02, 0x08, 0x31, 0x30, 0x35, 0x34, 0xFF, 0xFF, 0xFF, 0xEE }, 0, 13);
Console.WriteLine(port.BytesToWrite);
}
public void verifyChv(object s, SerialDataReceivedEventArgs e)
{
byte[] buffer = new byte[port.ReadBufferSize];
int bytesRead = port.Read(buffer, 0, buffer.Length);
foreach (int bf in buffer)
{
rtbInfo.Text += bf.ToString("X");
}
}
private string InterpretarHex(object buffer, bool conEspacios = false)
{
string sol="";
object byteAux;
if (buffer.ToString().Length > 0)
{
byteAux = ((int)(Card.Asc((char)((Card.Mid(buffer.ToString(), 1, 1)[0]))))).ToString("X");
sol = byteAux.ToString();
for (var i = 2; i <= (buffer.ToString()).Length; i++)
{
byteAux = ((int)(Card.Asc((char)((Card.Mid(buffer.ToString(), i, 1)[0]))))).ToString("X");
if ((byteAux.ToString()).Length == 1)
byteAux = "0" + byteAux;
if ((conEspacios))
sol = sol + " " + byteAux;
else
sol = sol + byteAux;
}
}
return sol;
}
private void btnFormat_Click(object sender, EventArgs e)
{
}
private long SendAPDUandDisplay(int SendType, string ApduIn)
{
long SendAPDUandDisplay = 0;
return SendAPDUandDisplay;
}
private long SubmitIC()
{
long SubmitIC = 0;
return SubmitIC;
}
private long SelectFile(byte HiAddr, byte LoAddr)
{
long SelectFile = 0;
return SelectFile;
}
private long readRecord(byte RecNo, byte dataLen)
{
long readRecord = 0;
return readRecord;
}
private long writeRecord(int caseType, byte RecNo, byte maxLen, byte dataLen, ref byte[] ApduIn)
{
//sample code
byte[] data = System.Text.ASCIIEncoding.Default.GetBytes("Hello World\n");
port.Write(data, 0, data.Length);
return port.BytesToWrite;
}
private void cboReaders_SelectedIndexChanged(object sender, EventArgs e)
{
if(cboReaders.Items.Count>0)
{
if (cboReaders.SelectedIndex >= 0)
{
Console.WriteLine(cboReaders.Text);
}
else
{
cboReaders.Text = "COM1";
}
port = new SerialPort(cboReaders.Text, 9600, Parity.None, 8, StopBits.One);
port.Handshake = Handshake.None;
port.Encoding = Encoding.ASCII;
port.ReceivedBytesThreshold = 1;
initMenu();
EnableConnectButton();
}
else
{
rtbInfo.Text = "NO SERIAL/COM PORT DEVICE SEEN";
}
}
}
}