NdefRecord.java revision 590b73bc5b8e5f7b59bff1d9264a52388a5162e6
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 android.os.Parcel; 20import android.os.Parcelable; 21 22import java.lang.UnsupportedOperationException; 23 24/** 25 * NDEF Record data. 26 * <p> 27 * Immutable data class. An NDEF record always contains 28 * <ul> 29 * <li>3-bit TNF field 30 * <li>Variable length type 31 * <li>Variable length ID 32 * <li>Variable length payload 33 * </ul> 34 * The TNF (Type Name Format) field indicates how to interpret the type field. 35 * <p> 36 * This class represents a logical (unchunked) NDEF record. The underlying 37 * representation may be chunked across several NDEF records when the payload is 38 * large. 39 */ 40public class NdefRecord implements Parcelable { 41 /** 42 * Indicates no type, id, or payload is associated with this NDEF Record. 43 * <p> 44 * Type, id and payload fields must all be empty to be a valid TNF_EMPTY 45 * record. 46 */ 47 public static final short TNF_EMPTY = 0x00; 48 49 /** 50 * Indicates the type field uses the RTD type name format. 51 * <p> 52 * Use this TNF with RTD types such as RTD_TEXT, RTD_URI. 53 */ 54 public static final short TNF_WELL_KNOWN = 0x01; 55 56 /** 57 * Indicates the type field contains a value that follows the media-type BNF 58 * construct defined by RFC 2046. 59 */ 60 public static final short TNF_MIME_MEDIA = 0x02; 61 62 /** 63 * Indicates the type field contains a value that follows the absolute-URI 64 * BNF construct defined by RFC 3986. 65 */ 66 public static final short TNF_ABSOLUTE_URI = 0x03; 67 68 /** 69 * Indicates the type field contains a value that follows the RTD external 70 * name specification. 71 * <p> 72 * Note this TNF should not be used with RTD_TEXT or RTD_URI constants. 73 * Those are well known RTD constants, not external RTD constants. 74 */ 75 public static final short TNF_EXTERNAL_TYPE = 0x04; 76 77 /** 78 * Indicates the payload type is unknown. 79 * <p> 80 * This is similar to the "application/octet-stream" MIME type. The payload 81 * type is not explicitly encoded within the NDEF Message. 82 * <p> 83 * The type field must be empty to be a valid TNF_UNKNOWN record. 84 */ 85 public static final short TNF_UNKNOWN = 0x05; 86 87 /** 88 * Indicates the payload is an intermediate or final chunk of a chunked 89 * NDEF Record. 90 * <p> 91 * The payload type is specified in the first chunk, and subsequent chunks 92 * must use TNF_UNCHANGED with an empty type field. TNF_UNCHANGED must not 93 * be used in any other situation. 94 */ 95 public static final short TNF_UNCHANGED = 0x06; 96 97 /** 98 * Reserved TNF type. 99 * <p> 100 * The NFC Forum NDEF Specification v1.0 suggests for NDEF parsers to treat this 101 * value like TNF_UNKNOWN. 102 * @hide 103 */ 104 public static final short TNF_RESERVED = 0x07; 105 106 /** 107 * RTD Text type. For use with TNF_WELL_KNOWN. 108 */ 109 public static final byte[] RTD_TEXT = {0x54}; // "T" 110 111 /** 112 * RTD URI type. For use with TNF_WELL_KNOWN. 113 */ 114 public static final byte[] RTD_URI = {0x55}; // "U" 115 116 /** 117 * RTD Smart Poster type. For use with TNF_WELL_KNOWN. 118 */ 119 public static final byte[] RTD_SMART_POSTER = {0x53, 0x70}; // "Sp" 120 121 /** 122 * RTD Alternative Carrier type. For use with TNF_WELL_KNOWN. 123 */ 124 public static final byte[] RTD_ALTERNATIVE_CARRIER = {0x61, 0x63}; // "ac" 125 126 /** 127 * RTD Handover Carrier type. For use with TNF_WELL_KNOWN. 128 */ 129 public static final byte[] RTD_HANDOVER_CARRIER = {0x48, 0x63}; // "Hc" 130 131 /** 132 * RTD Handover Request type. For use with TNF_WELL_KNOWN. 133 */ 134 public static final byte[] RTD_HANDOVER_REQUEST = {0x48, 0x72}; // "Hr" 135 136 /** 137 * RTD Handover Select type. For use with TNF_WELL_KNOWN. 138 */ 139 public static final byte[] RTD_HANDOVER_SELECT = {0x48, 0x73}; // "Hs" 140 141 private static final byte FLAG_MB = (byte) 0x80; 142 private static final byte FLAG_ME = (byte) 0x40; 143 private static final byte FLAG_CF = (byte) 0x20; 144 private static final byte FLAG_SR = (byte) 0x10; 145 private static final byte FLAG_IL = (byte) 0x08; 146 147 private final byte mFlags; 148 private final short mTnf; 149 private final byte[] mType; 150 private final byte[] mId; 151 private final byte[] mPayload; 152 153 /** 154 * Construct an NDEF Record. 155 * <p> 156 * Applications should not attempt to manually chunk NDEF Records - the 157 * implementation of android.nfc will automatically chunk an NDEF Record 158 * when necessary (and only present a single logical NDEF Record to the 159 * application). So applications should not use TNF_UNCHANGED. 160 * 161 * @param tnf a 3-bit TNF constant 162 * @param type byte array, containing zero to 255 bytes, must not be null 163 * @param id byte array, containing zero to 255 bytes, must not be null 164 * @param payload byte array, containing zero to (2 ** 32 - 1) bytes, 165 * must not be null 166 */ 167 public NdefRecord(short tnf, byte[] type, byte[] id, byte[] payload) { 168 /* check arguments */ 169 if ((type == null) || (id == null) || (payload == null)) { 170 throw new IllegalArgumentException("Illegal null argument"); 171 } 172 173 /* generate flag */ 174 byte flags = FLAG_MB | FLAG_ME; 175 176 /* Determine if it is a short record */ 177 if(payload.length < 0xFF) { 178 flags |= FLAG_SR; 179 } 180 181 /* Determine if an id is present */ 182 if(id.length != 0) { 183 flags |= FLAG_IL; 184 } 185 186 mFlags = flags; 187 mTnf = tnf; 188 mType = type.clone(); 189 mId = id.clone(); 190 mPayload = payload.clone(); 191 } 192 193 /** 194 * Construct an NDEF Record from raw bytes. 195 * <p> 196 * Validation is performed to make sure the header is valid, and that 197 * the id, type and payload sizes appear to be valid. 198 * 199 * @throws FormatException if the data is not a valid NDEF record 200 */ 201 public NdefRecord(byte[] data) { 202 throw new UnsupportedOperationException(); 203 } 204 205 /** 206 * Returns the 3-bit TNF. 207 * <p> 208 * TNF is the top-level type. 209 */ 210 public short getTnf() { 211 return mTnf; 212 } 213 214 /** 215 * Returns the variable length Type field. 216 * <p> 217 * This should be used in conjunction with the TNF field to determine the 218 * payload format. 219 */ 220 public byte[] getType() { 221 return mType.clone(); 222 } 223 224 /** 225 * Returns the variable length ID. 226 */ 227 public byte[] getId() { 228 return mId.clone(); 229 } 230 231 /** 232 * Returns the variable length payload. 233 */ 234 public byte[] getPayload() { 235 return mPayload.clone(); 236 } 237 238 /** 239 * Return this NDEF Record as a byte array. 240 * @hide 241 */ 242 public byte[] toByteArray() { 243 return generate(mFlags, mTnf, mType, mId, mPayload); 244 } 245 246 public int describeContents() { 247 return 0; 248 } 249 250 public void writeToParcel(Parcel dest, int flags) { 251 dest.writeInt(mTnf); 252 dest.writeInt(mType.length); 253 dest.writeByteArray(mType); 254 dest.writeInt(mId.length); 255 dest.writeByteArray(mId); 256 dest.writeInt(mPayload.length); 257 dest.writeByteArray(mPayload); 258 } 259 260 public static final Parcelable.Creator<NdefRecord> CREATOR = 261 new Parcelable.Creator<NdefRecord>() { 262 public NdefRecord createFromParcel(Parcel in) { 263 short tnf = (short)in.readInt(); 264 int typeLength = in.readInt(); 265 byte[] type = new byte[typeLength]; 266 in.readByteArray(type); 267 int idLength = in.readInt(); 268 byte[] id = new byte[idLength]; 269 in.readByteArray(id); 270 int payloadLength = in.readInt(); 271 byte[] payload = new byte[payloadLength]; 272 in.readByteArray(payload); 273 274 return new NdefRecord(tnf, type, id, payload); 275 } 276 public NdefRecord[] newArray(int size) { 277 return new NdefRecord[size]; 278 } 279 }; 280 281 private native byte[] generate(short flags, short tnf, byte[] type, byte[] id, byte[] data); 282}