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; 23a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenenimport android.util.Log; 246be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton 25ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamiltonimport java.io.IOException; 26ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton 276be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton/** 2874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Provides access to NFC-F (JIS 6319-4) properties and I/O operations on a {@link Tag}. 296be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton * 3074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>Acquire a {@link NfcF} object using {@link #get}. 3174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>The primary NFC-F 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 NfcF extends BasicTagTechnology { 38a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen private static final String TAG = "NFC"; 39a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen 40438feb9b3b7f79ab56abf47f817e6326fa8d7fe1Martijn Coenen /** @hide */ 41438feb9b3b7f79ab56abf47f817e6326fa8d7fe1Martijn Coenen public static final String EXTRA_SC = "systemcode"; 42438feb9b3b7f79ab56abf47f817e6326fa8d7fe1Martijn Coenen /** @hide */ 43438feb9b3b7f79ab56abf47f817e6326fa8d7fe1Martijn Coenen public static final String EXTRA_PMM = "pmm"; 44438feb9b3b7f79ab56abf47f817e6326fa8d7fe1Martijn Coenen 45438feb9b3b7f79ab56abf47f817e6326fa8d7fe1Martijn Coenen private byte[] mSystemCode = null; 46438feb9b3b7f79ab56abf47f817e6326fa8d7fe1Martijn Coenen private byte[] mManufacturer = null; 47438feb9b3b7f79ab56abf47f817e6326fa8d7fe1Martijn Coenen 484e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton /** 4974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Get an instance of {@link NfcF} for the given tag. 5074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>Returns null if {@link NfcF} was not enumerated in {@link Tag#getTechList}. 5174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * This indicates the tag does not support NFC-F. 5274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>Does not cause any RF activity and does not block. 534e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton * 5474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @param tag an NFC-F compatible tag 5574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @return NFC-F object 564e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton */ 574e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton public static NfcF get(Tag tag) { 584e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton if (!tag.hasTech(TagTechnology.NFC_F)) return null; 594e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton try { 604e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton return new NfcF(tag); 614e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton } catch (RemoteException e) { 624e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton return null; 634e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton } 644e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton } 654e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton 66ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton /** @hide */ 674e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton public NfcF(Tag tag) throws RemoteException { 684e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton super(tag, TagTechnology.NFC_F); 694e21e1d21a877cce4db5ec8c5786604cc10f2d7eJeff Hamilton Bundle extras = tag.getTechExtras(TagTechnology.NFC_F); 70438feb9b3b7f79ab56abf47f817e6326fa8d7fe1Martijn Coenen if (extras != null) { 71438feb9b3b7f79ab56abf47f817e6326fa8d7fe1Martijn Coenen mSystemCode = extras.getByteArray(EXTRA_SC); 72438feb9b3b7f79ab56abf47f817e6326fa8d7fe1Martijn Coenen mManufacturer = extras.getByteArray(EXTRA_PMM); 73438feb9b3b7f79ab56abf47f817e6326fa8d7fe1Martijn Coenen } 74438feb9b3b7f79ab56abf47f817e6326fa8d7fe1Martijn Coenen } 75438feb9b3b7f79ab56abf47f817e6326fa8d7fe1Martijn Coenen 7674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly /** 7774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Return the System Code bytes from tag discovery. 7874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 7974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>Does not cause any RF activity and does not block. 8074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 8174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @return System Code bytes 8274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly */ 83438feb9b3b7f79ab56abf47f817e6326fa8d7fe1Martijn Coenen public byte[] getSystemCode() { 84438feb9b3b7f79ab56abf47f817e6326fa8d7fe1Martijn Coenen return mSystemCode; 85438feb9b3b7f79ab56abf47f817e6326fa8d7fe1Martijn Coenen } 86438feb9b3b7f79ab56abf47f817e6326fa8d7fe1Martijn Coenen 8774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly /** 8874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Return the Manufacturer bytes from tag discovery. 8974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 9074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>Does not cause any RF activity and does not block. 9174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 9274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @return Manufacturer bytes 9374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly */ 94438feb9b3b7f79ab56abf47f817e6326fa8d7fe1Martijn Coenen public byte[] getManufacturer() { 95438feb9b3b7f79ab56abf47f817e6326fa8d7fe1Martijn Coenen return mManufacturer; 966be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton } 97ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton 98ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton /** 9974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * Send raw NFC-F commands to the tag and receive the response. 10074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 10174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>Applications must not append the SoD (length) or EoD (CRC) to the payload, 10274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * it will be automatically calculated. 10374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 104faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen * <p>Use {@link #getMaxTransceiveLength} to retrieve the maximum amount of bytes 105faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen * that can be sent with {@link #transceive}. 106faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen * 10774fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>This is an I/O operation and will block until complete. It must 10874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * not be called from the main application thread. A blocked call will be canceled with 10974fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * {@link IOException} if {@link #close} is called from another thread. 110ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton * 11139cf3a445e507f219ecc8a476f6038f095d9d520Nick Pelly * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. 11239cf3a445e507f219ecc8a476f6038f095d9d520Nick Pelly * 113ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton * @param data bytes to send 114ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton * @return bytes received in response 11574fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @throws TagLostException if the tag leaves the field 11674fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @throws IOException if there is an I/O failure, or this operation is canceled 117ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton */ 118ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton public byte[] transceive(byte[] data) throws IOException { 119ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton return transceive(data, true); 120ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton } 121a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen 122a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen /** 123faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen * Return the maximum number of bytes that can be sent with {@link #transceive}. 124faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen * @return the maximum number of bytes that can be sent with {@link #transceive}. 125faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen */ 126faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen public int getMaxTransceiveLength() { 127faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen return getMaxTransceiveLengthInternal(); 128faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen } 129faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen 130faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen /** 13182328bfd40008d85917cc01a1b2eb8eed1f23ec4Nick Pelly * Set the {@link #transceive} timeout in milliseconds. 13282328bfd40008d85917cc01a1b2eb8eed1f23ec4Nick Pelly * 13382328bfd40008d85917cc01a1b2eb8eed1f23ec4Nick Pelly * <p>The timeout only applies to {@link #transceive} on this object, 13482328bfd40008d85917cc01a1b2eb8eed1f23ec4Nick Pelly * and is reset to a default value when {@link #close} is called. 13582328bfd40008d85917cc01a1b2eb8eed1f23ec4Nick Pelly * 136a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen * <p>Setting a longer timeout may be useful when performing 137a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen * transactions that require a long processing time on the tag 138a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen * such as key generation. 139a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen * 140a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. 141a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen * 142a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen * @param timeout timeout value in milliseconds 143a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen */ 144a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen public void setTimeout(int timeout) { 145a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen try { 146112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen int err = mTag.getTagService().setTimeout(TagTechnology.NFC_F, timeout); 147112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen if (err != ErrorCodes.SUCCESS) { 148112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen throw new IllegalArgumentException("The supplied timeout is not valid"); 149112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen } 150a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen } catch (RemoteException e) { 151a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen Log.e(TAG, "NFC service dead", e); 152a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen } 153a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen } 15420e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen 15520e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen /** 15682328bfd40008d85917cc01a1b2eb8eed1f23ec4Nick Pelly * Get the current {@link #transceive} timeout in milliseconds. 15720e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen * 15820e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. 15920e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen * 16020e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen * @return timeout value in milliseconds 16120e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen */ 16220e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen public int getTimeout() { 16320e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen try { 16420e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen return mTag.getTagService().getTimeout(TagTechnology.NFC_F); 16520e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen } catch (RemoteException e) { 16620e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen Log.e(TAG, "NFC service dead", e); 16720e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen return 0; 16820e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen } 16920e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen } 1706be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton} 171