IsoDep.java revision 74fe6c6b245ebe7d3b3d96962c32980d88dca4f5
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.nfc.tech; 18 19import android.nfc.Tag; 20import android.os.Bundle; 21import android.os.RemoteException; 22import android.util.Log; 23 24import java.io.IOException; 25 26/** 27 * Provides access to ISO-DEP (ISO 14443-4) properties and I/O operations on a {@link Tag}. 28 * 29 * <p>Acquire a {@link IsoDep} object using {@link #get}. 30 * <p>The primary ISO-DEP I/O operation is {@link #transceive}. Applications must 31 * implement their own protocol stack on top of {@link #transceive}. 32 * <p>Tags that enumerate the {@link IsoDep} technology in {@link Tag#getTechList} 33 * will also enumerate 34 * {@link NfcA} or {@link NfcB} (since IsoDep builds on top of either of these). 35 */ 36public final class IsoDep extends BasicTagTechnology { 37 private static final String TAG = "NFC"; 38 39 /** @hide */ 40 public static final String EXTRA_HI_LAYER_RESP = "hiresp"; 41 /** @hide */ 42 public static final String EXTRA_HIST_BYTES = "histbytes"; 43 44 private byte[] mHiLayerResponse = null; 45 private byte[] mHistBytes = null; 46 47 /** 48 * Get an instance of {@link IsoDep} for the given tag. 49 * <p>Does not cause any RF activity and does not block. 50 * <p>Returns null if {@link IsoDep} was not enumerated in {@link Tag#getTechList}. 51 * This indicates the tag does not support ISO-DEP. 52 * 53 * @param tag an ISO-DEP compatible tag 54 * @return ISO-DEP object 55 */ 56 public static IsoDep get(Tag tag) { 57 if (!tag.hasTech(TagTechnology.ISO_DEP)) return null; 58 try { 59 return new IsoDep(tag); 60 } catch (RemoteException e) { 61 return null; 62 } 63 } 64 65 /** @hide */ 66 public IsoDep(Tag tag) 67 throws RemoteException { 68 super(tag, TagTechnology.ISO_DEP); 69 Bundle extras = tag.getTechExtras(TagTechnology.ISO_DEP); 70 if (extras != null) { 71 mHiLayerResponse = extras.getByteArray(EXTRA_HI_LAYER_RESP); 72 mHistBytes = extras.getByteArray(EXTRA_HIST_BYTES); 73 } 74 } 75 76 /** 77 * Set the timeout of {@link #transceive} in milliseconds. 78 * <p>The timeout only applies to ISO-DEP {@link #transceive}, and is 79 * reset to a default value when {@link #close} is called. 80 * <p>Setting a longer timeout may be useful when performing 81 * transactions that require a long processing time on the tag 82 * such as key generation. 83 * @param timeout timeout value in milliseconds 84 */ 85 public void setTimeout(int timeout) { 86 try { 87 mTag.getTagService().setIsoDepTimeout(timeout); 88 } catch (RemoteException e) { 89 Log.e(TAG, "NFC service dead", e); 90 } 91 } 92 93 @Override 94 public void close() throws IOException { 95 try { 96 mTag.getTagService().resetIsoDepTimeout(); 97 } catch (RemoteException e) { 98 Log.e(TAG, "NFC service dead", e); 99 } 100 super.close(); 101 } 102 103 /** 104 * Return the ISO-DEP historical bytes for {@link NfcA} tags. 105 * <p>Does not cause any RF activity and does not block. 106 * <p>The historical bytes can be used to help identify a tag. They are present 107 * only on {@link IsoDep} tags that are based on {@link NfcA} RF technology. 108 * If this tag is not {@link NfcA} then null is returned. 109 * <p>In ISO 14443-4 terminology, the historical bytes are a subset of the RATS 110 * response. 111 * 112 * @return ISO-DEP historical bytes, or null if this is not a {@link NfcA} tag 113 */ 114 public byte[] getHistoricalBytes() { 115 return mHistBytes; 116 } 117 118 /** 119 * Return the higher layer response bytes for {@link NfcB} tags. 120 * <p>Does not cause any RF activity and does not block. 121 * <p>The higher layer response bytes can be used to help identify a tag. 122 * They are present only on {@link IsoDep} tags that are based on {@link NfcB} 123 * RF technology. If this tag is not {@link NfcB} then null is returned. 124 * <p>In ISO 14443-4 terminology, the higher layer bytes are a subset of the 125 * ATTRIB response. 126 * 127 * @return ISO-DEP historical bytes, or null if this is not a {@link NfcB} tag 128 */ 129 public byte[] getHiLayerResponse() { 130 return mHiLayerResponse; 131 } 132 133 /** 134 * Send raw ISO-DEP data to the tag and receive the response. 135 * 136 * <p>Applications must only send the INF payload, and not the start of frame and 137 * end of frame indicators. Applications do not need to fragment the payload, it 138 * will be automatically fragmented and defragmented by {@link #transceive} if 139 * it exceeds FSD/FSC limits. 140 * 141 * <p>This is an I/O operation and will block until complete. It must 142 * not be called from the main application thread. A blocked call will be canceled with 143 * {@link IOException} if {@link #close} is called from another thread. 144 * 145 * @param data command bytes to send, must not be null 146 * @return response bytes received, will not be null 147 * @throws TagLostException if the tag leaves the field 148 * @throws IOException if there is an I/O failure, or this operation is canceled 149 */ 150 public byte[] transceive(byte[] data) throws IOException { 151 return transceive(data, true); 152 } 153} 154