IsoDep.java revision 3fcedf77286a078ebd7ac8c082365bd80703dfdc
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 * A low-level connection to a {@link Tag} using the ISO-DEP technology, also known as
28 * ISO1443-4.
29 *
30 * <p>You can acquire this kind of connection with {@link #get}.
31 * Use this class to send and receive data with {@link #transceive transceive()}.
32 *
33 * <p>Applications must implement their own protocol stack on top of
34 * {@link #transceive transceive()}.
35 *
36 * <p class="note"><strong>Note:</strong>
37 * Use of this class requires the {@link android.Manifest.permission#NFC}
38 * permission.
39 */
40public final class IsoDep extends BasicTagTechnology {
41    private static final String TAG = "NFC";
42
43    /** @hide */
44    public static final String EXTRA_HI_LAYER_RESP = "hiresp";
45    /** @hide */
46    public static final String EXTRA_HIST_BYTES = "histbytes";
47
48    private byte[] mHiLayerResponse = null;
49    private byte[] mHistBytes = null;
50
51    /**
52     * Returns an instance of this tech for the given tag. If the tag doesn't support
53     * this tech type null is returned.
54     *
55     * @param tag The tag to get the tech from
56     */
57    public static IsoDep get(Tag tag) {
58        if (!tag.hasTech(TagTechnology.ISO_DEP)) return null;
59        try {
60            return new IsoDep(tag);
61        } catch (RemoteException e) {
62            return null;
63        }
64    }
65
66    /** @hide */
67    public IsoDep(Tag tag)
68            throws RemoteException {
69        super(tag, TagTechnology.ISO_DEP);
70        Bundle extras = tag.getTechExtras(TagTechnology.ISO_DEP);
71        if (extras != null) {
72            mHiLayerResponse = extras.getByteArray(EXTRA_HI_LAYER_RESP);
73            mHistBytes = extras.getByteArray(EXTRA_HIST_BYTES);
74        }
75    }
76
77    /**
78     * Sets the timeout of an IsoDep transceive transaction in milliseconds.
79     * If the transaction has not completed before the timeout,
80     * any ongoing {@link #transceive} operation will be
81     * aborted and the connection to the tag is lost. This setting is applied
82     * only to the {@link Tag} object linked to this technology and will be
83     * reset when {@link IsoDep#close} is called.
84     * The default transaction timeout is 300 milliseconds.
85     */
86    public void setTimeout(int timeout) {
87        try {
88            mTag.getTagService().setIsoDepTimeout(timeout);
89        } catch (RemoteException e) {
90            Log.e(TAG, "NFC service dead", e);
91        }
92    }
93
94    @Override
95    public void close() throws IOException {
96        try {
97            mTag.getTagService().resetIsoDepTimeout();
98        } catch (RemoteException e) {
99            Log.e(TAG, "NFC service dead", e);
100        }
101        super.close();
102    }
103
104    /**
105     * Return the historical bytes if the tag is using {@link NfcA}, null otherwise.
106     */
107    public byte[] getHistoricalBytes() {
108        return mHistBytes;
109    }
110
111    /**
112     * Return the hi layer response bytes if the tag is using {@link NfcB}, null otherwise.
113     */
114    public byte[] getHiLayerResponse() {
115        return mHiLayerResponse;
116    }
117
118    /**
119     * Send data to a tag and receive the response.
120     * <p>
121     * This method will block until the response is received. It can be canceled
122     * with {@link #close}.
123     * <p>Requires {@link android.Manifest.permission#NFC} permission.
124     *
125     * @param data bytes to send
126     * @return bytes received in response
127     * @throws IOException if the target is lost or connection closed
128     */
129    public byte[] transceive(byte[] data) throws IOException {
130        return transceive(data, true);
131    }
132}
133