RFID-ISO14443电子钱包程序设计
该电子钱包程序是使用Java写的,核心代码分为两部分:第一部分是数据处理部分,主要功能是处理阅读器响应的数据,得到自己想要的数据。我们主要处理的是状态码,命令码和数据部分。另一部分是发送指令的程序,发送程序的代码中,大部分字段都是一样的,不同的指令,我们只用改变命令码和数据部分即可。具体代码如下:
处理数据的代码:
private void processAFrame_14443(String frameStr) {
byte[] framedata = ByteUtils.hexStr2Byte(frameStr);
byte statusCode = framedata[2];
curCMD_14443 = framedata[3];
byte LByte = framedata[6];
byte HByte = framedata[5];
int dataLength = HByte*256+LByte;
System.out.println(statusCode+" "+HByte+" "+LByte+" "+dataLength);
System.out.println(curCMD_14443);
String dataByte = "";
if(dataLength>0)
{
dataByte = frameStr.substring(14,14+dataLength*2);
}
System.out.println(dataByte);
if(statusCode==0x10||statusCode==0x11||statusCode==0x12)
{
dataView.append("命令失败"+"\r\n");
}else {
switch (curCMD_14443) {
case 0x01:
if(statusCode==0x00)
{
dataView.append("请求卡类型成功:返回值:{" +dataByte+"}"+ "\r\n");
}else {
dataView.append("请求卡失败"+"\r\n");
}
break;
case 0x02:
if(statusCode==0x00)
{
cardNum = dataByte;
findCardFile.setText(cardNum);
dataView.append("寻卡成功: 卡号为:{" +dataByte+"}"+ "\r\n");
if(dataByte.length()<8)
{
dataView.append("卡号长度不足4字节"+"\r\n");
}
}else {
dataView.append("寻卡失败"+"\r\n");
}
break;
case 0x03:
if(statusCode==0x00)
{
dataView.append("选定一张卡成功:返回值:{" +dataByte+"}"+ "\r\n");
}else {
dataView.append("选定一张卡失败"+"\r\n");
}
break;
case 0x04:
if(statusCode==0x00)
{
dataView.append("认证密钥成功:返回值:{" +dataByte+"}"+ "\r\n");
}else {
dataView.append("认证密钥失败"+"\r\n");
}
break;
case 0x05:
if(statusCode==0x00)
{
dataView.append("读块成功:块数据:{" +dataByte+"}"+ "\r\n");
}else {
dataView.append("读块失败"+"\r\n");
}
break;
case 0x06:
if(statusCode==0x00)
{
dataView.append("写块成功:返回值:{" +dataByte+"}"+ "\r\n");
}else {
dataView.append("写块失败"+"\r\n");
}
break;
case 0x07:
if(statusCode==0x00)
{
dataView.append("命令卡进入休眠状态:返回值:{" +dataByte+"}"+ "\r\n");
}else {
dataView.append("命令卡进入休眠状态失败"+"\r\n");
}
break;
case 0x08:
if(statusCode==0x00)
{
dataView.append("充值成功:返回值:{" +dataByte+"}"+ "\r\n");
}else {
dataView.append("充值失败"+"\r\n");
}
break;
case 0x09:
if(statusCode==0x00)
{
dataView.append("扣款成功:返回值:{" +dataByte+"}"+ "\r\n");
}else {
dataView.append("扣款失败"+"\r\n");
}
break;
case 0x0A:
if(statusCode==0x00)
{
dataView.append("读取当前钱数:当前钱数:{" +dataByte+"}"+ "\r\n");
quer.setText(dataByte);
}else {
dataView.append("读取当前钱数失败"+"\r\n");
}
break;
default:
break;
}
}
}
发送数据代码:
private void sendData(byte cmd,byte[] data) {
if(serialport==null)
{
ShowUtils.warningMessage("串口不存在!");
}
int datalen = data.length;
byte[] frame = new byte[datalen+11];
frame[0] = (byte) 0xEE;
frame[1] = (byte) 0xCC;
frame[2] = cmd;
frame[3] = (byte) 0x03;
frame[4] = (byte) 0x00;
frame[5] = (byte) (datalen/256);
frame[6] = (byte) (datalen%256);
for(int i = 0;i<datalen;i++)
{
frame[7+i] = data[i];
}
frame[7+datalen] = (byte) 0x00;
frame[8+datalen] = (byte) 0x00;
frame[9+datalen] = (byte) 0x0D;
frame[10+datalen] = (byte) 0x0A;
curCMD_14443 = cmd;
try {
SerialPortManager.sendToPort(serialport, frame);
} catch (SendDataToSerialPortFailure e) {
e.printStackTrace();
} catch (SerialPortOutputStreamCloseFailure e) {
e.printStackTrace();
}
}
下面是程序运行截图:
(1) 请求卡类型
发送:EECC 01 03 00 0001 01 0000 0D0A //请求所有
响应:EECC 00 01 03 0002 0001 0000 0D0A //卡片类型为0001
(2) 寻卡:
发送:EECC 02 03 00 0001 00 0000 0D0A
响应:EECC 00 02 03 0004 12345678 0000 0D0A //卡号为:12345678
(3)选择:
发送:EECC 03 03 00 0004 12345678 0000 0D0A //选择 12345678卡
响应:EECC 00 03 03 0001 00 0000 0D0A
(4) 秘钥认证:
发送:EECC 04 03 00 000C 013DFFFFFFFFFFFF12345678 0000 0D0A //以秘钥B、块号7为例
响应:EECC 00 04 03 0001 00 0000 0D0A
(5) 充值
发送:EECC 08 03 00 0004 00000004 00000 D0A //充值4元
响应:EECC 00 08 03 0001 00 0000 0D0A
(6) 扣费
发送:EECC 09 03 00 0004 00000002 00000D0A //扣除2元
响应:EECC 00 09 03 0001 00 00000D0A
(7) 查询
发送:EECC 0A 03 00 0001 00 0000 0D0A
响应:EECC 00 0A 03 0004 00000002 0000 0D0A //读取当前钱数为:2元
需要完整代码的可以在评论区留下邮箱地址。