Java 从acr1252u向iOS/Android设备发送长NDEF消息
我正在用Java开发一个应用程序,我想在NDEF消息中发送一个URL,然后在移动设备上打开。例如,我可以通过Mifare Ultralight的卡片模拟模式为URL执行此操作”http://www.google.com“因为这适合模拟卡的内存,如果我理解正确的话,内存是52字节,但是我想发送更长的URL(大约350-550字节),这在这个设备上的HCE可能是不可能的。acr1252也支持点对点通信,但不确定如何使用它来完成任务。有谁能给我指出一个能在这件事上帮助我的方向吗 我使用HCE用于较短URL的代码:Java 从acr1252u向iOS/Android设备发送长NDEF消息,java,nfc,ndef,hce,nfc-p2p,Java,Nfc,Ndef,Hce,Nfc P2p,我正在用Java开发一个应用程序,我想在NDEF消息中发送一个URL,然后在移动设备上打开。例如,我可以通过Mifare Ultralight的卡片模拟模式为URL执行此操作”http://www.google.com“因为这适合模拟卡的内存,如果我理解正确的话,内存是52字节,但是我想发送更长的URL(大约350-550字节),这在这个设备上的HCE可能是不可能的。acr1252也支持点对点通信,但不确定如何使用它来完成任务。有谁能给我指出一个能在这件事上帮助我的方向吗 我使用HCE用于较短U
public static void main(String[] args) throws CardException {
TerminalFactory factory = TerminalFactory.getDefault();
List<CardTerminal> terminals = factory.terminals().list();
System.out.println("Terminals: " + terminals);
CardTerminal terminal = terminals.get(0);
Card device = terminal.connect("DIRECT");
enterHostCardEmulation(device);
byte[] ndef = new byte[] {(byte) 0xE1, 0x10, 0x06, 0x00,
0x03, 0x0F, (byte) 0xD1, 0x01,
0x0B, 0x55, 0x01, 0x67,
0x6F, 0x6F, 0x67, 0x6C,
0x65, 0x2E, 0x63, 0x6F,
0x6D, (byte) 0xFE, 0x00, 0x00};
byte[] response = writeCardEmulationData(device, (byte) 0x01, (byte) 0x00, ndef);
System.out.println("response: " + byteArrayToHex(response));
}
private static byte[] writeCardEmulationData(Card device, byte nfcMode, byte startOffset, byte[] dataToWrite) {
byte[] command = new byte[9+dataToWrite.length];
command[0] = (byte) 0xE0; // Class
command[1] = 0x00; // INS
command[2] = 0x00; // P1
command[3] = 0x60; // P2
command[4] = (byte) (dataToWrite.length + 0x04); // Length + 4
command[5] = 0x01;
command[6] = nfcMode;
command[7] = startOffset;
command[8] = (byte) dataToWrite.length;
System.arraycopy(dataToWrite, 0, command, 9, dataToWrite.length);
System.out.println(byteArrayToHex(command));
try {
return device.transmitControlCommand(SCARD_CTL_CODE(3500), command);
} catch (CardException e) {
e.printStackTrace();
return null;
}
}
private static void enterHostCardEmulation(Card device) {
try {
System.out.println("NFC device: " + device);
byte[] hceCommand = new byte[] {(byte) 0xE0, 0x00, 0x00, 0x40, 0x03, 0x01, 0x00, 0x00};
byte[] hceResponse = device.transmitControlCommand(SCARD_CTL_CODE(3500), hceCommand);
System.out.println("enter HCE response: " + byteArrayToHex(hceResponse));
} catch (CardException e) {
e.printStackTrace();
}
}
private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
public static String byteArrayToHex(byte[] byteArr) {
char[] hexChars = new char[byteArr.length * 2];
for (int j = 0; j < byteArr.length; j++) {
int v = byteArr[j] & 0xFF;
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
}
return new String(hexChars);
}
public static int SCARD_CTL_CODE(int command) {
boolean isWindows = System.getProperty("os.name").startsWith("Windows");
if (isWindows) {
return 0x00310000 | (command << 2);
} else {
return 0x42000000 | command;
}
}
publicstaticvoidmain(字符串[]args)抛出CardException{
TerminalFactory=TerminalFactory.getDefault();
列表端子=工厂.terminals().List();
System.out.println(“终端:+终端”);
CardTerminal=terminals.get(0);
卡设备=终端连接(“直接”);
输入主机卡仿真(设备);
字节[]ndef=新字节[]{(字节)0xE1、0x10、0x06、0x00,
0x03,0x0F,(字节)0xD1,0x01,
0x0B,0x55,0x01,0x67,
0x6F,0x6F,0x67,0x6C,
0x65、0x2E、0x63、0x6F、,
0x6D,(字节)0xFE,0x00,0x00};
byte[]响应=写入模拟数据(设备,(字节)0x01,(字节)0x00,ndef);
System.out.println(“响应:+bytearraythex(响应));
}
专用静态字节[]writeCardEmulationData(卡设备,字节nfcMode,字节startOffset,字节[]dataToWrite){
byte[]命令=新字节[9+dataToWrite.length];
命令[0]=(字节)0xE0;//类
命令[1]=0x00;//INS
命令[2]=0x00;//P1
命令[3]=0x60;//P2
命令[4]=(字节)(dataToWrite.length+0x04);//长度+4
命令[5]=0x01;
命令[6]=nfcMode;
命令[7]=startOffset;
命令[8]=(字节)dataToWrite.length;
System.arraycopy(dataToWrite,0,command,9,dataToWrite.length);
System.out.println(bytearraythex(命令));
试一试{
返回装置。传输控制命令(SCARD\U CTL\U代码(3500),命令);
}捕获(卡例外){
e、 printStackTrace();
返回null;
}
}
私有静态无效enterHostCardEmulation(卡设备){
试一试{
System.out.println(“NFC设备:+设备”);
byte[]hceCommand=新字节[]{(字节)0xE0、0x00、0x00、0x40、0x03、0x01、0x00、0x00};
字节[]hceResponse=设备.传输控制命令(SCARD\U CTL\U代码(3500),hceCommand);
System.out.println(“输入HCE响应:+byteArrayToHex(HCERResponse));
}捕获(卡例外){
e、 printStackTrace();
}
}
私有静态final char[]HEX_ARRAY=“0123456789ABCDEF”.toCharArray();
公共静态字符串byteArrayToHex(字节[]byteArr){
char[]hexChars=新字符[byteArr.length*2];
对于(int j=0;j>>4];
hexChars[j*2+1]=十六进制数组[v&0x0F];
}
返回新字符串(hexChars);
}
公共静态int SCARD\U CTL\U代码(int命令){
布尔值isWindows=System.getProperty(“os.name”).startsWith(“Windows”);
如果(iWindows){
返回0x00310000 |(命令对等Nfc模式不是答案
iOS不支持Nfc点对点,因此您将无法向iPhone发送数据
Android确实支持Nfc点对点(称为Android Beam)但是它已经被弃用并从Android 10开始删除,删除它的原因之一是它非常不可靠,所以即使发送少量数据。我相信reader也支持FeliCa Type 3卡模拟160字节的数据。请看,是的,这是正确的。感谢您的回复。我没有提到我也尝试过这种方法ach.然而,我的URL大约有350-500字节长。因此,无论是类型2还是类型3卡模拟都不能满足我使用此读卡器的情况。好吧,这是意料之中的,但我是否能够通过Android HostApdUse做类似的事情,当您收到APDU命令时(例如,选择帮助)您可以通过软件定义并发送相应的响应?这样我就可以以多个“块”的形式发送消息,而不必担心将其存储在设备的内存中。我从未见过任何带有“直接”的USB读卡器模式,可能是因为有时间限制来响应可能无法通过USB的低级命令。我相信通过IC2或SPI从Arduino或Raspberry PiThrough方法直接访问pn532芯片就可以完成这类操作。这看起来甚至可以通过USB实现。这是否适用于我的读者?在数据表中,我没有发现acr1252有什么NFC芯片。