/* NFCard is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. NFCard is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Wget. If not, see <http://www.gnu.org/licenses/>. Additional permission under GNU GPL version 3 section 7 */ package com.zzx.factorytest.nfc.card; import android.content.res.Resources; import android.nfc.tech.NfcV; import com.zzx.factorytest.R; import com.zzx.factorytest.nfc.Util; final class VicinityCard { private static final int SYS_UNKNOWN = 0x00000000; private static final int SYS_SZLIB = 0x00010000; private static final int DEP_SZLIB_CENTER = 0x0100; private static final int DEP_SZLIB_NANSHAN = 0x0200; private static final int SRV_USER = 0x0001; private static final int SRV_BOOK = 0x0002; public static final int SW1_OK = 0x00; static String load(NfcV tech, Resources res) { String data = null; try { tech.connect(); int pos, BLKSIZE, BLKCNT; byte cmd[], rsp[], ID[], RAW[], STA[], flag, DSFID; ID = tech.getTag().getId(); if (ID == null || ID.length != 8) throw new Exception(); /*--------------------------------------------------------------*/ // get system information /*--------------------------------------------------------------*/ cmd = new byte[10]; cmd[0] = (byte) 0x22; // flag cmd[1] = (byte) 0x2B; // command System.arraycopy(ID, 0, cmd, 2, ID.length); // UID rsp = tech.transceive(cmd); if (rsp[0] != SW1_OK) throw new Exception(); pos = 10; flag = rsp[1]; DSFID = ((flag & 0x01) == 0x01) ? rsp[pos++] : 0; if ((flag & 0x02) == 0x02) pos++; if ((flag & 0x04) == 0x04) { BLKCNT = rsp[pos++] + 1; BLKSIZE = (rsp[pos++] & 0xF) + 1; } else { BLKCNT = BLKSIZE = 0; } /*--------------------------------------------------------------*/ // read first 8 block /*--------------------------------------------------------------*/ cmd = new byte[12]; cmd[0] = (byte) 0x22; // flag cmd[1] = (byte) 0x23; // command System.arraycopy(ID, 0, cmd, 2, ID.length); // UID cmd[10] = (byte) 0x00; // index of first block to get cmd[11] = (byte) 0x07; // block count, one less! (see ISO15693-3) rsp = tech.transceive(cmd); if (rsp[0] != SW1_OK) throw new Exception(); RAW = rsp; /*--------------------------------------------------------------*/ // read last block /*--------------------------------------------------------------*/ cmd[10] = (byte) (BLKCNT - 1); // index of first block to get cmd[11] = (byte) 0x00; // block count, one less! (see ISO15693-3) rsp = tech.transceive(cmd); if (rsp[0] != SW1_OK) throw new Exception(); STA = rsp; data = Util.toHexString(rsp, 0, rsp.length); /*--------------------------------------------------------------*/ // build result string /*--------------------------------------------------------------*/ final int type = parseType(DSFID, RAW, BLKSIZE); final String name = parseName(type, res); final String info = parseInfo(ID, res); final String extra = parseData(type, RAW, STA, BLKSIZE, res); data = CardManager.buildResult(name, info, extra, null); } catch (Exception e) { data = null; // data = e.getMessage(); } try { tech.close(); } catch (Exception e) { } return data; } private static int parseType(byte dsfid, byte[] raw, int blkSize) { int ret = SYS_UNKNOWN; if (blkSize == 4 && (raw[4] & 0x10) == 0x10 && (raw[14] & 0xAB) == 0xAB && (raw[13] & 0xE0) == 0xE0) { ret = SYS_SZLIB; if ((raw[13] & 0x0F) == 0x05) ret |= DEP_SZLIB_CENTER; else ret |= DEP_SZLIB_NANSHAN; if (raw[4] == 0x12) ret |= SRV_USER; else ret |= SRV_BOOK; } return ret; } private static String parseName(int type, Resources res) { if ((type & SYS_SZLIB) == SYS_SZLIB) { final String dep; if ((type & DEP_SZLIB_CENTER) == DEP_SZLIB_CENTER) dep = res.getString(R.string.name_szlib_center); else if ((type & DEP_SZLIB_NANSHAN) == DEP_SZLIB_NANSHAN) dep = res.getString(R.string.name_szlib_nanshan); else dep = null; final String srv; if ((type & SRV_BOOK) == SRV_BOOK) srv = res.getString(R.string.name_lib_booktag); else if ((type & SRV_USER) == SRV_USER) srv = res.getString(R.string.name_lib_readercard); else srv = null; if (dep != null && srv != null) return dep + " " + srv; } return res.getString(R.string.name_unknowntag); } private static String parseInfo(byte[] id, Resources res) { final StringBuilder r = new StringBuilder(); final String i = res.getString(R.string.lab_id); r.append("<b>").append(i).append("</b> ") .append(Util.toHexStringR(id, 0, id.length)); return r.toString(); } private static String parseData(int type, byte[] raw, byte[] sta, int blkSize, Resources res) { if ((type & SYS_SZLIB) == SYS_SZLIB) { return parseSzlibData(type, raw, sta, blkSize, res); } return null; } private static String parseSzlibData(int type, byte[] raw, byte[] sta, int blkSize, Resources res) { long id = 0; for (int i = 3; i > 0; --i) id = (id <<= 8) | (0x000000FF & raw[i]); for (int i = 8; i > 4; --i) id = (id <<= 8) | (0x000000FF & raw[i]); final String sid; if ((type & SRV_USER) == SRV_USER) sid = res.getString(R.string.lab_user_id); else sid = res.getString(R.string.lab_bktg_sn); final StringBuilder r = new StringBuilder(); r.append("<b>").append(sid).append(" <font color=\"teal\">"); r.append(String.format("%013d", id)).append("</font></b><br />"); final String scat; if ((type & SRV_BOOK) == SRV_BOOK) { final byte cat = raw[12]; if ((type & DEP_SZLIB_NANSHAN) == DEP_SZLIB_NANSHAN) { if (cat == 0x10) scat = res.getString(R.string.name_bkcat_soc); else if (cat == 0x20) { if (raw[11] == (byte) 0x84) scat = res.getString(R.string.name_bkcat_ltr); else scat = res.getString(R.string.name_bkcat_sci); } else scat = null; } else { scat = null; } if (scat != null) { final String scl = res.getString(R.string.lab_bkcat); r.append("<b>").append(scl).append("</b> ").append(scat) .append("<br />"); } } // final int len = raw.length; // for (int i = 1, n = 0; i < len; i += blkSize) { // final String blk = Util.toHexString(raw, i, blkSize); // r.append("<br />").append(n++).append(": ").append(blk); // } // final String blk = Util.toHexString(sta, 0, blkSize); // r.append("<br />S: ").append(blk); return r.toString(); } }