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 * 1016711e0203305ff7de001cc5ce557f878bf95a938Martijn Coenen * <p>Applications must not prefix the SoD (preamble and sync code) 1026711e0203305ff7de001cc5ce557f878bf95a938Martijn Coenen * and/or append the EoD (CRC) to the payload, it will be automatically calculated. 1036711e0203305ff7de001cc5ce557f878bf95a938Martijn Coenen * 1046711e0203305ff7de001cc5ce557f878bf95a938Martijn Coenen * <p>A typical NFC-F frame for this method looks like: 1056711e0203305ff7de001cc5ce557f878bf95a938Martijn Coenen * <pre> 1066711e0203305ff7de001cc5ce557f878bf95a938Martijn Coenen * LENGTH (1 byte) --- CMD (1 byte) -- IDm (8 bytes) -- PARAMS (LENGTH - 10 bytes) 1076711e0203305ff7de001cc5ce557f878bf95a938Martijn Coenen * </pre> 10874fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * 109faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen * <p>Use {@link #getMaxTransceiveLength} to retrieve the maximum amount of bytes 110faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen * that can be sent with {@link #transceive}. 111faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen * 11274fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * <p>This is an I/O operation and will block until complete. It must 11374fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * not be called from the main application thread. A blocked call will be canceled with 11474fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * {@link IOException} if {@link #close} is called from another thread. 115ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton * 11639cf3a445e507f219ecc8a476f6038f095d9d520Nick Pelly * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. 11739cf3a445e507f219ecc8a476f6038f095d9d520Nick Pelly * 118ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton * @param data bytes to send 119ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton * @return bytes received in response 12074fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @throws TagLostException if the tag leaves the field 12174fe6c6b245ebe7d3b3d96962c32980d88dca4f5Nick Pelly * @throws IOException if there is an I/O failure, or this operation is canceled 122ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton */ 123ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton public byte[] transceive(byte[] data) throws IOException { 124ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton return transceive(data, true); 125ce3224cda51f946871daa1e11e3976e25c59e6faJeff Hamilton } 126a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen 127a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen /** 128faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen * Return the maximum number of bytes that can be sent with {@link #transceive}. 129faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen * @return the maximum number of bytes that can be sent with {@link #transceive}. 130faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen */ 131faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen public int getMaxTransceiveLength() { 132faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen return getMaxTransceiveLengthInternal(); 133faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen } 134faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen 135faca12adc62d148505fadfd286e6a2752c197fa0Martijn Coenen /** 13682328bfd40008d85917cc01a1b2eb8eed1f23ec4Nick Pelly * Set the {@link #transceive} timeout in milliseconds. 13782328bfd40008d85917cc01a1b2eb8eed1f23ec4Nick Pelly * 13882328bfd40008d85917cc01a1b2eb8eed1f23ec4Nick Pelly * <p>The timeout only applies to {@link #transceive} on this object, 13982328bfd40008d85917cc01a1b2eb8eed1f23ec4Nick Pelly * and is reset to a default value when {@link #close} is called. 14082328bfd40008d85917cc01a1b2eb8eed1f23ec4Nick Pelly * 141a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen * <p>Setting a longer timeout may be useful when performing 142a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen * transactions that require a long processing time on the tag 143a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen * such as key generation. 144a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen * 145a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. 146a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen * 147a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen * @param timeout timeout value in milliseconds 148a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen */ 149a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen public void setTimeout(int timeout) { 150a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen try { 151112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen int err = mTag.getTagService().setTimeout(TagTechnology.NFC_F, timeout); 152112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen if (err != ErrorCodes.SUCCESS) { 153112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen throw new IllegalArgumentException("The supplied timeout is not valid"); 154112fdf612db71a552fce063136bf2796df3b71ecMartijn Coenen } 155a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen } catch (RemoteException e) { 156a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen Log.e(TAG, "NFC service dead", e); 157a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen } 158a924973f22aedc580708625e4babb6deabc6b4d3Martijn Coenen } 15920e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen 16020e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen /** 16182328bfd40008d85917cc01a1b2eb8eed1f23ec4Nick Pelly * Get the current {@link #transceive} timeout in milliseconds. 16220e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen * 16320e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. 16420e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen * 16520e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen * @return timeout value in milliseconds 16620e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen */ 16720e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen public int getTimeout() { 16820e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen try { 16920e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen return mTag.getTagService().getTimeout(TagTechnology.NFC_F); 17020e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen } catch (RemoteException e) { 17120e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen Log.e(TAG, "NFC service dead", e); 17220e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen return 0; 17320e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen } 17420e62c9f1466ace5771e244f03a995dc0939b11bMartijn Coenen } 1756be655c768a82716612c00fdd156254d8dc00f42Jeff Hamilton} 176