2

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

不幸的是,我无法让下面的源代码正常工作。我希望“保持安静”命令之后的“库存”和“读取单个块”命令会失败,因为这两个命令都没有被寻址,处于安静状态的标签应该忽略。但我仍然从标签中得到包含 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};
}
4

1 回答 1

2

当您发送 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(第 5 位)为 1,Address_flag 为 0。

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

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

您对此无法控制,因此它可能会干扰您尝试使标签静音。

于 2013-11-05T11:57:22.650 回答