安卓NfcV保持安静命令



我正试图在Android手机(Nexus 4(上实现不同的NfcV命令。目前,我正在使用这些标签。根据数据表,他们应该支持"保持安静"-命令。

不幸的是,我无法使下面的源代码正常工作。我预计"保持安静"命令之后的"Inventory"one_answers"Read Single Block"命令会失败,因为这两个命令都未处理,处于安静状态的标签应该忽略这一点。但我仍然从标签中得到包含UID或有效载荷的正确答案。

此外,通过执行"保持安静"命令,我得到了一个"标签丢失"异常。然而,根据ISO 15693-3,标签不应该对此命令作出响应,这无论如何都可能导致此异常。

尽管如此,我猜这段代码中的"保持安静"命令有问题,但我不知道是什么。

感谢您的帮助。

源代码:

            NfcV nfcv = NfcV.get(mtag);

                try{
                    nfcv.connect();                                                             //Connect
                } catch(IOException e){
                    mUIDs = mUIDs + "nConnection Error 1";
                }

                byte[] response1 = {(byte) 0x00};
                try{
                    byte[] UIDreq1 = InventoryRequest();                                        //Inventory Request
                    response1 = nfcv.transceive(UIDreq1);
                } catch(IOException e){
                    mUIDs = mUIDs + "nInventory Error 1";
                }
                mUIDs = mUIDs +"n" + bytesToHex(response1);
                byte[] UID = response2UID(response1);
                mUIDs = mUIDs + "n" + bytesToHex(UID);

                try{
                    byte[] command = ReadSingleBlockUnadressed((byte) 0x04);                    //Reading Single Block
                    byte[] data = nfcv.transceive(command);
                    mUIDs = mUIDs +"n"+bytesToHex(data);
                }catch(IOException e){
                    Log.e("Reading Single Block", e.getMessage());
                    mUIDs = mUIDs + "nReading Error";
                }

                try{
                    try{
                        byte[] command = StayQuiet(UID);                                        //Stay Quiet, SHOULD FAIL
                        nfcv.transceive(command);
                    }catch(TagLostException e){
                        Log.e("Stay Quiet", e.getMessage());
                        mUIDs = mUIDs + "nTag was lost.";
                    }
                    }catch(IOException x){
                    mUIDs = mUIDs + "nStay Quiet Error";
                }

                try{
                    byte[] command = ReadSingleBlockUnadressed((byte) 0x04);                    //Reading Single Block
                    byte[] data = nfcv.transceive(command);
                    mUIDs = mUIDs +"n"+bytesToHex(data);
                }catch(IOException e){
                    Log.e("Reading Single Block", e.getMessage());
                    mUIDs = mUIDs + "nReading Error";
                }
                try{
                    byte[] UIDreq2 = InventoryRequest();                                        //Inventory Request, SHOULD FAIL
                    byte[] response2 = nfcv.transceive(UIDreq2);
                    mUIDs = mUIDs +"n" + bytesToHex(response2);
                } catch(IOException e){
                    mUIDs = mUIDs + "nInventory Error 2";
                }

                try{
                    nfcv.close();                                                               //Disconnect
                } catch(IOException x){
                    mUIDs = mUIDs + "nDisconnection Error 1";
                }

                mTagTextView.setText(mUIDs);

具有以下功能:

final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes) {
    char[] hexChars = new char[bytes.length * 2];
    int v;
    for ( int j = 0; j < bytes.length; j++ ) {
        v = bytes[j] & 0xFF;
        hexChars[j * 2] = hexArray[v >>> 4];
        hexChars[j * 2 + 1] = hexArray[v & 0x0F];
    }
    return new String(hexChars);
}
private byte[] response2UID(byte[] response){
    byte[] UID = new byte[response.length-2];
    for(int i = 2; i < response.length; i++){
        UID[i-2]=response[i];
    }
    return UID;
}
private byte[] ReadSingleBlockUnadressed(byte blocknumber){
    return new byte[] {(byte) 0x00, (byte) 0x20, blocknumber};
}
private byte[] StayQuiet(byte[] UID){
    byte[] beQuiet = new byte[] {(byte) 0x04, (byte) 0x02}; 
    byte[] command = combine(beQuiet, UID);
    return command;
}
private byte[] InventoryRequest(){
    return new byte[] { (byte) 0x24, (byte) 0x01, (byte) 0x00};
}

发送STAY QUITE命令时,会将标记从选中状态变为未选中状态。

然后,您将发送标志值为0x00的READ SINGLE BLOCK命令。

根据ISO/IEC 15693-3标准,这意味着Select_flag(比特5(为零。该标准对该位的用法定义如下:

Bit 5 = 0: Request shall be executed by any VICC according to the
setting of Address_flag
Bit 5 = 1: Request shall be executed only by VICC in selected state

Address_flag在这里定义(它的值为零(:

Bit 6 = 0: Request is not addressed. UID field is not present. It shall be
executed by any VICC.
Bit 6 = 1: Request is addressed. UID field is present. It shall be
executed only by the VICC whose UID matches the UID
specified in the request.

使用您在READ SINGLE BLOCK命令中使用的标志,您已经指示标记即使未选中也要应答。这就是它工作的原因。

对于您的用例,您希望Select_flag(Bit 5(为1,Address_flag为零。

我建议你看一下ISO/IEC 15693-3标准。可以在这里在线找到它的副本:http://www.waazaa.org/download/fcd-15693-3.pdf

顺便说一句,你会得到"标签丢失"的异常,因为NFC服务一直在检查标签的存在。在ISO15693的情况下,它可能是通过在背后发送INVENTORY命令来实现的,因为INVENTORY是所有ISO15693标签都能理解的少数命令之一。

你对此无法控制,所以它很可能会干扰你屏蔽标签的尝试。

最新更新