16be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton/* 26be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton * Copyright (C) 2010 The Android Open Source Project 36be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton * 46be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton * Licensed under the Apache License, Version 2.0 (the "License"); 56be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton * you may not use this file except in compliance with the License. 66be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton * You may obtain a copy of the License at 76be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton * 86be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton * http://www.apache.org/licenses/LICENSE-2.0 96be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton * 106be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton * Unless required by applicable law or agreed to in writing, software 116be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton * distributed under the License is distributed on an "AS IS" BASIS, 126be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton * See the License for the specific language governing permissions and 146be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton * limitations under the License. 156be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton */ 166be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton 174e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamiltonpackage android.nfc.tech; 186be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton 19112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenenimport android.nfc.ErrorCodes; 206be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport android.nfc.Tag; 216be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport android.os.Bundle; 226be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonimport android.os.RemoteException; 23112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenenimport android.util.Log; 246be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton 25ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamiltonimport java.io.IOException; 26ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton 276be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton/** 2874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Provides access to NFC-A (ISO 14443-3A) properties and I/O operations on a {@link Tag}. 296be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton * 3074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>Acquire a {@link NfcA} object using {@link #get}. 3174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>The primary NFC-A I/O operation is {@link #transceive}. Applications must 3274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * implement their own protocol stack on top of {@link #transceive}. 3339cf3a445e507f219ecc8a476f6038f095d9d520Nick Pelly * 3439cf3a445e507f219ecc8a476f6038f095d9d520Nick Pelly * <p class="note"><strong>Note:</strong> Methods that perform I/O operations 3539cf3a445e507f219ecc8a476f6038f095d9d520Nick Pelly * require the {@link android.Manifest.permission#NFC} permission. 366be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton */ 376be655c768a82716612c00fdd156254d8dc00f42Jeff Hamiltonpublic final class NfcA extends BasicTagTechnology { 38112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen private static final String TAG = "NFC"; 39112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen 406be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton /** @hide */ 416be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton public static final String EXTRA_SAK = "sak"; 426be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton /** @hide */ 436be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton public static final String EXTRA_ATQA = "atqa"; 446be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton 456be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton private short mSak; 466be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton private byte[] mAtqa; 476be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton 484e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton /** 4974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Get an instance of {@link NfcA} for the given tag. 5074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>Returns null if {@link NfcA} was not enumerated in {@link Tag#getTechList}. 5174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * This indicates the tag does not support NFC-A. 5274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>Does not cause any RF activity and does not block. 534e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton * 5474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @param tag an NFC-A compatible tag 5574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @return NFC-A object 564e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton */ 574e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton public static NfcA get(Tag tag) { 584e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton if (!tag.hasTech(TagTechnology.NFC_A)) return null; 594e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton try { 604e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton return new NfcA(tag); 614e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton } catch (RemoteException e) { 624e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton return null; 634e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton } 644e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton } 654e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton 66ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton /** @hide */ 674e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton public NfcA(Tag tag) throws RemoteException { 684e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton super(tag, TagTechnology.NFC_A); 694e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton Bundle extras = tag.getTechExtras(TagTechnology.NFC_A); 706be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton mSak = extras.getShort(EXTRA_SAK); 716be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton mAtqa = extras.getByteArray(EXTRA_ATQA); 726be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton } 736be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton 746be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton /** 7574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Return the ATQA/SENS_RES bytes from tag discovery. 7674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 7774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>Does not cause any RF activity and does not block. 7874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 7974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @return ATQA/SENS_RES bytes 806be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton */ 816be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton public byte[] getAtqa() { 826be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton return mAtqa; 836be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton } 846be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton 856be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton /** 8674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Return the SAK/SEL_RES bytes from tag discovery. 8774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 8874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>Does not cause any RF activity and does not block. 8974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 9074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @return SAK bytes 916be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton */ 926be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton public short getSak() { 936be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton return mSak; 946be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton } 95ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton 96ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton /** 9774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Send raw NFC-A commands to the tag and receive the response. 9874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 9974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>Applications must not append the EoD (CRC) to the payload, 10074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * it will be automatically calculated. 10174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>Applications must only send commands that are complete bytes, 10274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * for example a SENS_REQ is not possible (these are used to 10374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * manage tag polling and initialization). 10474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 105faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen * <p>Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes 106faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen * that can be sent with {@link #transceive}. 107faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen * 10874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>This is an I/O operation and will block until complete. It must 10974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * not be called from the main application thread. A blocked call will be canceled with 11074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * {@link IOException} if {@link #close} is called from another thread. 111ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton * 11239cf3a445e507f219ecc8a476f6038f095d9d520Nick Pelly * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. 11339cf3a445e507f219ecc8a476f6038f095d9d520Nick Pelly * 114ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton * @param data bytes to send 115ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton * @return bytes received in response 11674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @throws TagLostException if the tag leaves the field 11774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @throws IOException if there is an I/O failure, or this operation is canceled 118ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton */ 119ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton public byte[] transceive(byte[] data) throws IOException { 120ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton return transceive(data, true); 121ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton } 122112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen 123112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen /** 124faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen * Return the maximum number of bytes that can be sent with {@link #transceive}. 125faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen * @return the maximum number of bytes that can be sent with {@link #transceive}. 126faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen */ 127faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen public int getMaxTransceiveLength() { 128faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen return getMaxTransceiveLengthInternal(); 129faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen } 130faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen 131faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen /** 13282328bfd40008d85917cc01a1b2eb8eed1f23ec4Nick Pelly * Set the {@link #transceive} timeout in milliseconds. 13382328bfd40008d85917cc01a1b2eb8eed1f23ec4Nick Pelly * 13482328bfd40008d85917cc01a1b2eb8eed1f23ec4Nick Pelly * <p>The timeout only applies to {@link #transceive} on this object, 13582328bfd40008d85917cc01a1b2eb8eed1f23ec4Nick Pelly * and is reset to a default value when {@link #close} is called. 13682328bfd40008d85917cc01a1b2eb8eed1f23ec4Nick Pelly * 137112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen * <p>Setting a longer timeout may be useful when performing 138112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen * transactions that require a long processing time on the tag 139112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen * such as key generation. 140112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen * 141112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. 142112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen * 143112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen * @param timeout timeout value in milliseconds 144112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen */ 145112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen public void setTimeout(int timeout) { 146112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen try { 147112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen int err = mTag.getTagService().setTimeout(TagTechnology.NFC_A, timeout); 148112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen if (err != ErrorCodes.SUCCESS) { 149112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen throw new IllegalArgumentException("The supplied timeout is not valid"); 150112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen } 151112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen } catch (RemoteException e) { 152112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen Log.e(TAG, "NFC service dead", e); 153112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen } 154112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen } 15520e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen 15620e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen /** 15782328bfd40008d85917cc01a1b2eb8eed1f23ec4Nick Pelly * Get the current {@link #transceive} timeout in milliseconds. 15820e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen * 15920e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. 16020e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen * 16120e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen * @return timeout value in milliseconds 16220e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen */ 16320e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen public int getTimeout() { 16420e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen try { 16520e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen return mTag.getTagService().getTimeout(TagTechnology.NFC_A); 16620e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen } catch (RemoteException e) { 16720e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen Log.e(TAG, "NFC service dead", e); 16820e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen return 0; 16920e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen } 17020e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen } 1716be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton} 172