获取mifare卡序列号不正确

时间:2015-11-08 16:56:13

标签: c# rfid mifare smartcard-reader contactless-smartcard

使用我正在使用的读卡器,检索MIFARE卡序列号的协议如下:

  

Mifare防撞,0x0202
  功能卡防冲击
  格式aa bb 05 00 00 00 02 02 00
  回复aa bb 0a 00 52 51 02 02 00 46 ff a6 b8 a4

46 ff a6 b8是上述响应中的卡序列号。

我在C#中实现此协议如下:

private SerialPort _serialPort = new SerialPort();
private string _receivedData = null;

public MifareCardReader(string comPort, int baudRate)
{
    _serialPort = new SerialPort();
    _serialPort.PortName = comPort;
    _serialPort.BaudRate = baudRate;
    _serialPort.DataBits = 8;
    _serialPort.Parity = Parity.None;
    _serialPort.StopBits = StopBits.One;
    _serialPort.Handshake = Handshake.None;
    _serialPort.Open();   

    // Add event
    _serialPort.DataReceived += SerialPort_DataReceived;     
}

public string MifareAnticollision()
{
    if (_serialPort != null && _serialPort.IsOpen)
    {
        string message = "AABB050000000202000D";
        byte[] data = StringToByteArray(message);
        _serialPort.Write(data, 0, data.Length);
    }
}

private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    _receivedData += _serialPort.ReadExisting();
    byte[] data = Encoding.ASCII.GetBytes(receivedData);
    if (data.Length >= 9)
    {
        if (data[8] == 0) // OK
        {
            // Response data is complete
            if (data.Length == 14)
            {
                StringBuilder hex = new StringBuilder(8);
                hex.AppendFormat("{0:X2}", data[9]);
                hex.AppendFormat("{0:X2}", data[10]);
                hex.AppendFormat("{0:X2}", data[11]);
                hex.AppendFormat("{0:X2}", data[12]);

                string cardID = hex.ToString();
                _receivedData = string.Empty;
            }
        }
        else // fail
        {
            _receivedData = string.Empty;
        }
    }
}

我使用3种不同的MIFARE卡进行了测试,但输出并不是我的预期:

  • 卡1:已收到:3F463F3F,预计:974682D6
  • 卡片2:已收到:3F450B3F,预计:EA450B91
  • 卡3:已收到:070D3F3F,预计:070DEBD6

我需要更改什么才能获得正确的输出?

1 个答案:

答案 0 :(得分:1)

您遇到的问题似乎是将值0x7F以上的字节替换为0x3F(问号(“?”)字符)。即只有7位值正确显示,第8位设置的值变为“?” (0x3F)。例如。对于卡1,974682D6被“收到”为3F463F3F,因为0x970x820xD6的第8位已设置。

此问题的根源是您使用ReadExisting()方法从串行端口读取字符串值。默认情况下,ReadExisting()从串行端口读取字节,使用ASCII编码(System.Text.ASCIIEncoding)进行转换,并返回结果字符串。然后,您接受该字符串并将其转换回字节数组(再次使用ASCII编码)。

有问题的步骤是使用System.Text.ASCIIEncoding / Encoding.ASCII进行的转化。 documentation说:

  

由于ASCII是7位编码,因此ASCII字符仅限于最低128 个Unicode字符,从U + 0000到U + 007F。在执行编码操作之前, [...] 该范围之外的字符被问号(?)替换。

因此,您应该使用Read()ReadByte()方法将字节直接读入字节数组。例如。与

byte[] buffer = new byte[_serialPort.ReadBufferSize];
int bytesRead = _serialPort.Read(buffer, 0, buffer.Length);