NfcF.java revision a924973f22aedc580708625e4babb6deabc6b4d3
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 NFC-F (JIS 6319-4) properties and I/O operations on a {@link Tag}.
28 *
29 * <p>Acquire a {@link NfcF} object using {@link #get}.
30 * <p>The primary NFC-F I/O operation is {@link #transceive}. Applications must
31 * implement their own protocol stack on top of {@link #transceive}.
32 *
33 * <p class="note"><strong>Note:</strong> Methods that perform I/O operations
34 * require the {@link android.Manifest.permission#NFC} permission.
35 */
36public final class NfcF extends BasicTagTechnology {
37    private static final String TAG = "NFC";
38
39    /** @hide */
40    public static final String EXTRA_SC = "systemcode";
41    /** @hide */
42    public static final String EXTRA_PMM = "pmm";
43
44    private byte[] mSystemCode = null;
45    private byte[] mManufacturer = null;
46
47    /**
48     * Get an instance of {@link NfcF} for the given tag.
49     * <p>Returns null if {@link NfcF} was not enumerated in {@link Tag#getTechList}.
50     * This indicates the tag does not support NFC-F.
51     * <p>Does not cause any RF activity and does not block.
52     *
53     * @param tag an NFC-F compatible tag
54     * @return NFC-F object
55     */
56    public static NfcF get(Tag tag) {
57        if (!tag.hasTech(TagTechnology.NFC_F)) return null;
58        try {
59            return new NfcF(tag);
60        } catch (RemoteException e) {
61            return null;
62        }
63    }
64
65    /** @hide */
66    public NfcF(Tag tag) throws RemoteException {
67        super(tag, TagTechnology.NFC_F);
68        Bundle extras = tag.getTechExtras(TagTechnology.NFC_F);
69        if (extras != null) {
70            mSystemCode = extras.getByteArray(EXTRA_SC);
71            mManufacturer = extras.getByteArray(EXTRA_PMM);
72        }
73    }
74
75    /**
76     * Return the System Code bytes from tag discovery.
77     *
78     * <p>Does not cause any RF activity and does not block.
79     *
80     * @return System Code bytes
81     */
82    public byte[] getSystemCode() {
83      return mSystemCode;
84    }
85
86    /**
87     * Return the Manufacturer bytes from tag discovery.
88     *
89     * <p>Does not cause any RF activity and does not block.
90     *
91     * @return Manufacturer bytes
92     */
93    public byte[] getManufacturer() {
94      return mManufacturer;
95    }
96
97    /**
98     * Send raw NFC-F commands to the tag and receive the response.
99     *
100     * <p>Applications must not append the SoD (length) or EoD (CRC) to the payload,
101     * it will be automatically calculated.
102     *
103     * <p>This is an I/O operation and will block until complete. It must
104     * not be called from the main application thread. A blocked call will be canceled with
105     * {@link IOException} if {@link #close} is called from another thread.
106     *
107     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
108     *
109     * @param data bytes to send
110     * @return bytes received in response
111     * @throws TagLostException if the tag leaves the field
112     * @throws IOException if there is an I/O failure, or this operation is canceled
113     */
114    public byte[] transceive(byte[] data) throws IOException {
115        return transceive(data, true);
116    }
117
118    /**
119     * Set the timeout of {@link #transceive} in milliseconds.
120     * <p>The timeout only applies to NfcF {@link #transceive}, and is
121     * reset to a default value when {@link #close} is called.
122     * <p>Setting a longer timeout may be useful when performing
123     * transactions that require a long processing time on the tag
124     * such as key generation.
125     *
126     * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
127     *
128     * @param timeout timeout value in milliseconds
129     * @hide
130     */
131    // TODO Unhide for ICS
132    public void setTimeout(int timeout) {
133        try {
134            mTag.getTagService().setFelicaTimeout(timeout);
135        } catch (RemoteException e) {
136            Log.e(TAG, "NFC service dead", e);
137        }
138    }
139}
140