采用Android NfcV的TI NFC写单块(ISO 15693)

时间:2016-02-05 23:27:28

标签: android nfc texas-instruments iso-15693

我正在编写和Android应用程序通过ISO15693与RF430FRL152H设备进行通信。此应用程序尝试复制使用TRF7970A与设备通信的现有Qt C ++可执行文件。

如果设置了选项标志,我一直无法编写单个块,从而导致android.nfc.TagLostException。

TRF7970A可执行文件遵循TRF7960评估模式文档,该文档指出写单块(0x21)必须设置选项标志(0x40)。

我在自己的应用中观察到此行为以及来自TI论坛的示例Android应用:https://e2e.ti.com/support/wireless_connectivity/nfc_rfid/f/667/p/469938/1688321#1688321

Android Issue Tracker上的2011年帖子提到了Android的nfcV的一些问题,并在通用芯片上写了块,包括TI:https://code.google.com/p/android/issues/detail?id=15608

在我的应用程序中,这确实可以防止android.nfc.TagLostException,并且不会返回错误标志。但是,当我在固件通用控制寄存器中启用和设置中断字段时,我没有观察到预期的行为,所以我不确定这是一个完整的解决方案。

为了使问题更加复杂,从TRF7970A可执行文件中的写命令中删除选项标志继续正常工作。

这是编写单个块的正确方法吗? Android和TI设备之间是否存在已知问题,特别是RF430FRL152H?

public class MainActivity extends AppCompatActivity {
    static final String LOG_TAG = MainActivity.class.getSimpleName();

    NfcAdapter mNfcAdapter;
    NfcV mNfcV;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
    }

    private void enableForegroundDispatch() {
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

        final IntentFilter intentFilter = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);

        IntentFilter[] intentFilters = new IntentFilter[] { intentFilter };

        String[][] techListArray = new String[][] { new String[] { NfcV.class.getName() }};

        mNfcAdapter.enableForegroundDispatch(this, pendingIntent, intentFilters, techListArray);
    }

    @Override
    public void onPause() {
        super.onPause();
        mNfcAdapter.disableForegroundDispatch(this);
    }

    @Override
    public void onResume() {
        super.onResume();
        enableForegroundDispatch();
    }

    @Override
    protected void onNewIntent(Intent intent) {
        switch(intent.getAction())
        {
            case NfcAdapter.ACTION_TECH_DISCOVERED:
                onNfcTagDiscoveredAction(intent);
                break;

            default:
                break;
        }
    }

    private void onNfcTagDiscoveredAction(Intent intent) {
        if(mNfcV != null) {
            return;
        }

        Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

        mNfcV = NfcV.get(tag);

        AsyncTask<Void, Void, Void> asyncTask = new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... params) {
                try {
                    mNfcV.connect();

                    // TRF7970A "010C00030410002101000000" Register Write Request
                    // TRF7970A "0109000304F0000000" AGC Toggle
                    // TRF7970A "0109000304F1FF0000" AM PM Toggle
                    // TRF7970A "010B000304142401000000" ISO 15693 Inventory request
                    final byte[] INVENTORY = new byte[] { (byte) 0x24, (byte) 0x01, (byte) 0x00 };
                    byte[] inventoryResult = mNfcV.transceive(INVENTORY);

                    Log.d(LOG_TAG, "Inventory complete");

                    // TRF7970A "010C00030418002312010000"
                    final byte[] READ_MULTIPLE_BLOCK = new byte[] { (byte)0x00, (byte)0x23, (byte)0x12, (byte)0x01 };
                    byte[] readResult = mNfcV.transceive(READ_MULTIPLE_BLOCK);

                    Log.d(LOG_TAG, "Read multiple block complete, result length: " + readResult.length);

                    // TRF7970A "010F000304180221ff95fe00000000" Request mode
                    final byte[] WRITE_SINGLE_BLOCK_NO_OPTION = new byte[] { (byte)0x02, (byte)0x21, (byte)0xff, (byte)0x95, (byte)0xfe, (byte)0x00, (byte)0x00 };
                    byte[] noOptionResult = mNfcV.transceive(WRITE_SINGLE_BLOCK_NO_OPTION);

                    Log.d(LOG_TAG, "Wrote no option, result length: " + noOptionResult.length);

                    // TRF7970 "010F00030418402101010100000000" Request Mode
                    final byte[] WRITE_SINGLE_BLOCK_OPTION = new byte[] { (byte)0x40, (byte)0x21, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x00, (byte)0x00 };
                    byte[] optionResult = mNfcV.transceive(WRITE_SINGLE_BLOCK_OPTION);

                    Log.d(LOG_TAG, "Wrote with option, result length: " + optionResult.length);
                }
                catch(Exception e) {
                    Log.d(LOG_TAG, "Exception: " + e.toString());
                }
                return null;
            }

            @Override
            protected void onPostExecute(Void result)
            {
                mNfcV = null;
            }
        };
        asyncTask.execute();
    }
}

0 个答案:

没有答案