Tag.java revision a926540d5455a973dd8ca19c00c108620d9c68c2
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;
18
19import java.util.HashMap;
20
21import android.os.Parcel;
22import android.os.Parcelable;
23
24/**
25 * Represents a (generic) discovered tag.
26 * <p>
27 * A tag is a passive NFC element, such as NFC Forum Tag's, Mifare class Tags,
28 * Sony Felica Tags.
29 * <p>
30 * Tag's have a type and usually have a UID.
31 * <p>
32 * {@link Tag} objects are passed to applications via the {@link NfcAdapter#EXTRA_TAG} extra
33 * in {@link NfcAdapter#ACTION_TAG_DISCOVERED} intents. A {@link Tag} object is immutable
34 * and represents the state of the tag at the time of discovery. It can be
35 * directly queried for its UID and Type, or used to create a {@link RawTagConnection}
36 * (with {@link NfcAdapter#createRawTagConnection createRawTagConnection()}).
37 * <p>
38 * A {@link Tag} can  be used to create a {@link RawTagConnection} only while the tag is in
39 * range. If it is removed and then returned to range, then the most recent
40 * {@link Tag} object (in {@link NfcAdapter#ACTION_TAG_DISCOVERED}) should be used to create a
41 * {@link RawTagConnection}.
42 * <p>This is an immutable data class.
43 */
44public class Tag implements Parcelable {
45
46    /**
47     * @hide
48     */
49    public static final int NFC_TAG_ISO14443_A = 1; /* phNfc_eISO14443_A_PICC */
50
51    /**
52     * @hide
53     */
54    public static final int NFC_TAG_ISO14443_4A = 2; /* phNfc_eISO14443_4A_PICC */
55
56    /**
57     * @hide
58     */
59    public static final int NFC_TAG_ISO14443_3A = 3; /* phNfc_eISO14443_3A_PICC */
60
61    /**
62     * @hide
63     */
64    public static final int NFC_TAG_MIFARE = 4; /* phNfc_eMifare_PICC */
65
66    /**
67     * @hide
68     */
69    public static final int NFC_TAG_ISO14443_B = 5; /* phNfc_eISO14443_B_PICC */
70
71    /**
72     * @hide
73     */
74    public static final int NFC_TAG_ISO14443_4B = 6; /* phNfc_eISO14443_4B_PICC */
75
76    /**
77     * @hide
78     */
79    public static final int NFC_TAG_ISO14443_B_PRIME = 7; /* phNfc_eISO14443_BPrime_PICC */
80
81    /**
82     * @hide
83     */
84    public static final int NFC_TAG_FELICA = 8; /* phNfc_eFelica_PICC */
85
86    /**
87     * @hide
88     */
89    public static final int NFC_TAG_JEWEL = 9; /* phNfc_eJewel_PICC */
90
91    /**
92     * @hide
93     */
94    public static final int NFC_TAG_ISO15693 = 10; /* phNfc_eISO15693_PICC */
95
96    /**
97     * @hide
98     */
99    public static final int NFC_TAG_OTHER = 11; /* phNfc_ePICC_DevType */
100
101
102    public static final String TARGET_ISO_14443_3A = "iso14443_3a";
103
104    public static final String TARGET_ISO_14443_3B = "iso14443_3b";
105
106    public static final String TARGET_ISO_14443_3B_PRIME = "iso14443_3b";
107
108    public static final String TARGET_ISO_14443_4 = "iso14443_4";
109
110    public static final String TARGET_ISO_15693 = "iso15693";
111
112    public static final String TARGET_JIS_X_6319_4 = "jis_x_6319_4";
113
114    public static final String TARGET_TOPAZ = "topaz";
115
116    public static final String TARGET_OTHER = "other";
117
118    /*package*/ final String mTypeName;
119    /*package*/ final boolean mIsNdef;
120    /*package*/ final byte[] mUid;
121    /*package*/ final int mNativeHandle;
122
123    /*package*/ static final String INTERNAL_TARGET_TYPE_ISO14443_3A = "Iso14443-3A";
124    /*package*/ static final String INTERNAL_TARGET_TYPE_ISO14443_3B = "Iso14443-3B";
125    /*package*/ static final String INTERNAL_TARGET_TYPE_ISO14443_4 = "Iso14443-4";
126    /*package*/ static final String INTERNAL_TARGET_TYPE_MIFARE_UL = "MifareUL";
127    /*package*/ static final String INTERNAL_TARGET_TYPE_MIFARE_1K = "Mifare1K";
128    /*package*/ static final String INTERNAL_TARGET_TYPE_MIFARE_4K = "Mifare4K";
129    /*package*/ static final String INTERNAL_TARGET_TYPE_MIFARE_DESFIRE = "MifareDESFIRE";
130    /*package*/ static final String INTERNAL_TARGET_TYPE_MIFARE_UNKNOWN = "Unknown Mifare";
131    /*package*/ static final String INTERNAL_TARGET_TYPE_FELICA = "Felica";
132    /*package*/ static final String INTERNAL_TARGET_TYPE_JEWEL = "Jewel";
133    /*package*/ static final String INTERNAL_TARGET_TYPE_UNKNOWN = "Unknown Type";
134
135	private static final HashMap<String, Integer> INT_TYPES_CONVERTION_TABLE = new HashMap<String, Integer>() {
136		{
137			put(Tag.INTERNAL_TARGET_TYPE_ISO14443_3A, Tag.NFC_TAG_ISO14443_A );
138			put(Tag.INTERNAL_TARGET_TYPE_ISO14443_3B, Tag.NFC_TAG_ISO14443_B );
139			put(Tag.INTERNAL_TARGET_TYPE_MIFARE_UL, Tag.NFC_TAG_MIFARE );
140			put(Tag.INTERNAL_TARGET_TYPE_MIFARE_1K, Tag.NFC_TAG_MIFARE );
141			put(Tag.INTERNAL_TARGET_TYPE_MIFARE_4K, Tag.NFC_TAG_MIFARE );
142			put(Tag.INTERNAL_TARGET_TYPE_MIFARE_DESFIRE, Tag.NFC_TAG_MIFARE );
143			put(Tag.INTERNAL_TARGET_TYPE_FELICA, Tag.NFC_TAG_FELICA );
144			put(Tag.INTERNAL_TARGET_TYPE_JEWEL, Tag.NFC_TAG_JEWEL );
145		}
146	};
147
148	private int convertToInt(String internalTypeName) {
149		Integer result = INT_TYPES_CONVERTION_TABLE.get(internalTypeName);
150		if (result == null) {
151		    return Tag.NFC_TAG_OTHER;
152		}
153		return result;
154    }
155
156	private static final HashMap<String, String[]> RAW_TYPES_CONVERTION_TABLE = new HashMap<String, String[]>() {
157		{
158			/* TODO: handle multiprotocol */
159			put(Tag.INTERNAL_TARGET_TYPE_ISO14443_3A, new String[] { Tag.TARGET_ISO_14443_3A });
160			put(Tag.INTERNAL_TARGET_TYPE_ISO14443_3B, new String[] { Tag.TARGET_ISO_14443_3B });
161			put(Tag.INTERNAL_TARGET_TYPE_MIFARE_UL, new String[] { Tag.TARGET_ISO_14443_3A });
162			put(Tag.INTERNAL_TARGET_TYPE_MIFARE_1K, new String[] { Tag.TARGET_ISO_14443_3A });
163			put(Tag.INTERNAL_TARGET_TYPE_MIFARE_4K, new String[] { Tag.TARGET_ISO_14443_3A });
164			put(Tag.INTERNAL_TARGET_TYPE_MIFARE_DESFIRE, new String[] { Tag.TARGET_ISO_14443_3A });
165			put(Tag.INTERNAL_TARGET_TYPE_MIFARE_UNKNOWN, new String[] { Tag.TARGET_ISO_14443_3A });
166			put(Tag.INTERNAL_TARGET_TYPE_FELICA, new String[] { Tag.TARGET_JIS_X_6319_4 });
167			put(Tag.INTERNAL_TARGET_TYPE_JEWEL, new String[] { Tag.TARGET_TOPAZ });
168		}
169	};
170
171	private String[] convertToRaw(String internalTypeName) {
172	    String[] result =  RAW_TYPES_CONVERTION_TABLE.get(internalTypeName);
173	    if (result == null) {
174	        return new String[] { Tag.TARGET_OTHER };
175	    }
176	    return result;
177	}
178
179    /**
180     * Hidden constructor to be used by NFC service only.
181     * @hide
182     */
183    public Tag(String typeName, boolean isNdef, byte[] uid, int nativeHandle) {
184        mTypeName = typeName;
185        mIsNdef = isNdef;
186        mUid = uid.clone();
187        mNativeHandle = nativeHandle;
188    }
189
190    /**
191     * For use by NfcService only.
192     * @hide
193     */
194    public int getHandle() {
195        return mNativeHandle;
196    }
197
198    /**
199     * Return the available targets that this NFC adapter can use to create
200     * a RawTagConnection.
201     *
202     * @return
203     */
204    public String[] getRawTargets() {
205        return convertToRaw(mTypeName);
206    }
207
208    /**
209     * Get the Tag type.
210     * <p>
211     * The Tag type is one of the NFC_TAG constants. It is read at discovery
212     * time and this method does not cause any further RF activity and does not
213     * block.
214     *
215     * @return a NFC_TAG constant
216     * @hide
217     */
218    public int getType() {
219        return convertToInt(mTypeName);
220    }
221
222    /**
223     * Get the Tag Identifier (if it has one).
224     * <p>
225     * Tag ID is usually a serial number for the tag.
226     * <p>
227     * The Tag ID is read at discovery time and this method does not cause any
228     * further RF activity and does not block.
229     *
230     * @return ID, or null if it does not exist
231     */
232    public byte[] getId() {
233        if (mUid.length > 0) {
234            return mUid.clone();
235        } else {
236            return null;
237        }
238    }
239
240    @Override
241    public int describeContents() {
242        return 0;
243    }
244
245    @Override
246    public void writeToParcel(Parcel dest, int flags) {
247        boolean[] booleans = new boolean[] {mIsNdef};
248        dest.writeString(mTypeName);
249        dest.writeBooleanArray(booleans);
250        dest.writeInt(mUid.length);
251        dest.writeByteArray(mUid);
252        dest.writeInt(mNativeHandle);
253    }
254
255    public static final Parcelable.Creator<Tag> CREATOR =
256            new Parcelable.Creator<Tag>() {
257        public Tag createFromParcel(Parcel in) {
258            boolean[] booleans = new boolean[1];
259            String type = in.readString();
260            in.readBooleanArray(booleans);
261            boolean isNdef = booleans[0];
262            int uidLength = in.readInt();
263            byte[] uid = new byte[uidLength];
264            in.readByteArray(uid);
265            int nativeHandle = in.readInt();
266
267            return new Tag(type, isNdef, uid, nativeHandle);
268        }
269        public Tag[] newArray(int size) {
270            return new Tag[size];
271        }
272    };
273}