Java 从acr1252u向iOS/Android设备发送长NDEF消息

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

我正在用Java开发一个应用程序,我想在NDEF消息中发送一个URL,然后在移动设备上打开。例如,我可以通过Mifare Ultralight的卡片模拟模式为URL执行此操作”http://www.google.com“因为这适合模拟卡的内存,如果我理解正确的话,内存是52字节,但是我想发送更长的URL(大约350-550字节),这在这个设备上的HCE可能是不可能的。acr1252也支持点对点通信,但不确定如何使用它来完成任务。有谁能给我指出一个能在这件事上帮助我的方向吗

我使用HCE用于较短URL的代码:

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芯片。