10bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen/*
20bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen * Copyright (C) 2012 The Android Open Source Project
30bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen *
40bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen * Licensed under the Apache License, Version 2.0 (the "License");
50bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen * you may not use this file except in compliance with the License.
60bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen * You may obtain a copy of the License at
70bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen *
80bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen *      http://www.apache.org/licenses/LICENSE-2.0
90bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen *
100bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen * Unless required by applicable law or agreed to in writing, software
110bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen * distributed under the License is distributed on an "AS IS" BASIS,
120bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen * See the License for the specific language governing permissions and
140bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen * limitations under the License.
150bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen */
160bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen
170bec15ebed8b8639076cba184af3235e17f48718Martijn Coenenpackage android.nfc.tech;
180bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen
190bec15ebed8b8639076cba184af3235e17f48718Martijn Coenenimport android.nfc.Tag;
200bec15ebed8b8639076cba184af3235e17f48718Martijn Coenenimport android.os.Bundle;
210bec15ebed8b8639076cba184af3235e17f48718Martijn Coenenimport android.os.RemoteException;
220bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen
230bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen/**
240bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen * Provides access to tags containing just a barcode.
250bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen *
260bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen * <p>Acquire an {@link NfcBarcode} object using {@link #get}.
270bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen *
280bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen */
290bec15ebed8b8639076cba184af3235e17f48718Martijn Coenenpublic final class NfcBarcode extends BasicTagTechnology {
300bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen
310bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen    /** Kovio Tags */
320bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen    public static final int TYPE_KOVIO = 1;
330bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen    public static final int TYPE_UNKNOWN = -1;
340bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen
350bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen    /** @hide */
360bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen    public static final String EXTRA_BARCODE_TYPE = "barcodetype";
370bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen
380bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen    private int mType;
390bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen
400bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen    /**
410bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen     * Get an instance of {@link NfcBarcode} for the given tag.
420bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen     *
430bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen     * <p>Returns null if {@link NfcBarcode} was not enumerated in {@link Tag#getTechList}.
440bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen     *
450bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen     * <p>Does not cause any RF activity and does not block.
460bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen     *
470bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen     * @param tag an NfcBarcode compatible tag
480bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen     * @return NfcBarcode object
490bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen     */
500bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen    public static NfcBarcode get(Tag tag) {
510bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen        if (!tag.hasTech(TagTechnology.NFC_BARCODE)) return null;
520bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen        try {
530bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen            return new NfcBarcode(tag);
540bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen        } catch (RemoteException e) {
550bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen            return null;
560bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen        }
570bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen    }
580bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen
590bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen    /**
600bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen     * Internal constructor, to be used by NfcAdapter
610bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen     * @hide
620bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen     */
630bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen    public NfcBarcode(Tag tag) throws RemoteException {
640bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen        super(tag, TagTechnology.NFC_BARCODE);
650bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen        Bundle extras = tag.getTechExtras(TagTechnology.NFC_BARCODE);
660bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen        if (extras != null) {
670bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen            mType = extras.getInt(EXTRA_BARCODE_TYPE);
680bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen        } else {
690bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen            throw new NullPointerException("NfcBarcode tech extras are null.");
700bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen        }
710bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen    }
720bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen
730bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen    /**
740bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen     * Returns the NFC Barcode tag type.
750bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen     *
76ca0cf4ee782e474961e6de74f6004781773f957cMartijn Coenen     * <p>Currently only one of {@link #TYPE_KOVIO} or {@link #TYPE_UNKNOWN}.
770bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen     *
780bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen     * <p>Does not cause any RF activity and does not block.
790bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen     *
800bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen     * @return the NFC Barcode tag type
810bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen     */
820bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen    public int getType() {
830bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen        return mType;
840bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen    }
850bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen
860bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen    /**
870bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen     * Returns the barcode of an NfcBarcode tag.
880bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen     *
897a6dfb2f7294bbfb5ebc4f937db97b659a447607Martijn Coenen     * <p> Tags of {@link #TYPE_KOVIO} return 16 bytes:
907a6dfb2f7294bbfb5ebc4f937db97b659a447607Martijn Coenen     *     <ul>
917a6dfb2f7294bbfb5ebc4f937db97b659a447607Martijn Coenen     *     <p> The first byte is 0x80 ORd with a manufacturer ID, corresponding
927a6dfb2f7294bbfb5ebc4f937db97b659a447607Martijn Coenen     *       to ISO/IEC 7816-6.
937a6dfb2f7294bbfb5ebc4f937db97b659a447607Martijn Coenen     *     <p> The second byte describes the payload data format. Defined data
947a6dfb2f7294bbfb5ebc4f937db97b659a447607Martijn Coenen     *       format types include the following:<ul>
957a6dfb2f7294bbfb5ebc4f937db97b659a447607Martijn Coenen     *       <li>0x00: Reserved for manufacturer assignment</li>
967a6dfb2f7294bbfb5ebc4f937db97b659a447607Martijn Coenen     *       <li>0x01: 96-bit URL with "http://www." prefix</li>
977a6dfb2f7294bbfb5ebc4f937db97b659a447607Martijn Coenen     *       <li>0x02: 96-bit URL with "https://www." prefix</li>
987a6dfb2f7294bbfb5ebc4f937db97b659a447607Martijn Coenen     *       <li>0x03: 96-bit URL with "http://" prefix</li>
997a6dfb2f7294bbfb5ebc4f937db97b659a447607Martijn Coenen     *       <li>0x04: 96-bit URL with "https://" prefix</li>
1007a6dfb2f7294bbfb5ebc4f937db97b659a447607Martijn Coenen     *       <li>0x05: 96-bit GS1 EPC</li>
1017a6dfb2f7294bbfb5ebc4f937db97b659a447607Martijn Coenen     *       <li>0x06-0xFF: reserved</li>
1027a6dfb2f7294bbfb5ebc4f937db97b659a447607Martijn Coenen     *       </ul>
1037a6dfb2f7294bbfb5ebc4f937db97b659a447607Martijn Coenen     *     <p>The following 12 bytes are payload:<ul>
1047a6dfb2f7294bbfb5ebc4f937db97b659a447607Martijn Coenen     *       <li> In case of a URL payload, the payload is encoded in US-ASCII,
10535bf6288527b177a04100585321a1266f020004aMartijn Coenen     *            following the limitations defined in RFC3987.
10635bf6288527b177a04100585321a1266f020004aMartijn Coenen     *            {@see <a href="http://www.ietf.org/rfc/rfc3987.txt">RFC 3987</a>}</li>
10735bf6288527b177a04100585321a1266f020004aMartijn Coenen     *       <li> In case of GS1 EPC data, see <a href="http://www.gs1.org/gsmp/kc/epcglobal/tds/">
10835bf6288527b177a04100585321a1266f020004aMartijn Coenen     *            GS1 Electronic Product Code (EPC) Tag Data Standard (TDS)</a> for more details.
10935bf6288527b177a04100585321a1266f020004aMartijn Coenen     *       </li>
11035bf6288527b177a04100585321a1266f020004aMartijn Coenen     *     </ul>
1117a6dfb2f7294bbfb5ebc4f937db97b659a447607Martijn Coenen     *     <p>The last 2 bytes comprise the CRC.
1127a6dfb2f7294bbfb5ebc4f937db97b659a447607Martijn Coenen     *     </ul>
1130bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen     * <p>Does not cause any RF activity and does not block.
1140bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen     *
1150bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen     * @return a byte array containing the barcode
11635bf6288527b177a04100585321a1266f020004aMartijn Coenen     * @see <a href="http://www.kovio.com/docs/kovionfcbarcode.pdf">
11735bf6288527b177a04100585321a1266f020004aMartijn Coenen     *      Kovio 128-bit NFC barcode datasheet</a>
11835bf6288527b177a04100585321a1266f020004aMartijn Coenen     * @see <a href="http://kovio.com/docs/kovio-128-nfc-barcode-data-format.pdf">
11935bf6288527b177a04100585321a1266f020004aMartijn Coenen     *      Kovio 128-bit NFC barcode data format</a>
1200bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen     */
1210bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen    public byte[] getBarcode() {
1220bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen        switch (mType) {
1230bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen            case TYPE_KOVIO:
1240bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen                // For Kovio tags the barcode matches the ID
1250bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen                return mTag.getId();
1260bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen            default:
1270bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen                return null;
1280bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen        }
1290bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen    }
1300bec15ebed8b8639076cba184af3235e17f48718Martijn Coenen}
131