From: pk910 Date: Wed, 27 Jan 2016 21:38:30 +0000 (+0100) Subject: Implemented NFC Card Reader Code from https://git.sterul.com/student-projects/dhbw... X-Git-Url: http://git.pk910.de/?p=DHBWCampusApp.git;a=commitdiff_plain;h=bd624f87e88e024b0c680f989cf008941fccc17f Implemented NFC Card Reader Code from https://git.sterul.com/student-projects/dhbw-card-reader --- diff --git a/app/src/main/java/com/codebutler/farebot/Utils.java b/app/src/main/java/com/codebutler/farebot/Utils.java deleted file mode 100644 index c77b93c..0000000 --- a/app/src/main/java/com/codebutler/farebot/Utils.java +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Utils.java - * - * Copyright (C) 2011 Eric Butler - * - * Authors: - * Eric Butler - * - * This program 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. - * - * This program 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 this program. If not, see . - */ - -package com.codebutler.farebot; - -import android.app.Activity; -import android.app.AlertDialog; -import android.content.DialogInterface; -import android.util.Log; -import android.view.WindowManager; - -import com.codebutler.farebot.card.desfire.DesfireException; -import com.codebutler.farebot.card.desfire.DesfireFileSettings; -import com.codebutler.farebot.card.desfire.DesfireProtocol; - -import org.w3c.dom.Node; - -import java.io.StringWriter; -import java.util.List; - -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Result; -import javax.xml.transform.Source; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - -public class Utils { - - private static final String TAG = Utils.class.getName(); - - public static void showError (final Activity activity, Exception ex) { - Log.e(activity.getClass().getName(), ex.getMessage(), ex); - new AlertDialog.Builder(activity) - .setMessage(Utils.getErrorMessage(ex)) - .show(); - } - - public static void showErrorAndFinish (final Activity activity, Exception ex) { - try { - Log.e(activity.getClass().getName(), Utils.getErrorMessage(ex)); - ex.printStackTrace(); - - new AlertDialog.Builder(activity) - .setMessage(Utils.getErrorMessage(ex)) - .setCancelable(false) - .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface arg0, int arg1) { - activity.finish(); - } - }) - .show(); - } catch (WindowManager.BadTokenException unused) { - /* Ignore... happens if the activity was destroyed */ - } - } - - public static String getHexString (byte[] b) throws Exception { - String result = ""; - for (int i=0; i < b.length; i++) { - result += Integer.toString( ( b[i] & 0xff ) + 0x100, 16).substring( 1 ); - } - return result; - } - - public static String getHexString (byte[] b, String defaultResult) { - try { - return getHexString(b); - } catch (Exception ex) { - return defaultResult; - } - } - - public static byte[] hexStringToByteArray (String s) { - if ((s.length() % 2) != 0) { - throw new IllegalArgumentException("Bad input string: " + s); - } - - int len = s.length(); - byte[] data = new byte[len / 2]; - for (int i = 0; i < len; i += 2) { - data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) - + Character.digit(s.charAt(i+1), 16)); - } - return data; - } - - /* - public static byte[] intToByteArray(int value) { - return new byte[] { - (byte)(value >>> 24), - (byte)(value >>> 16), - (byte)(value >>> 8), - (byte)value}; - } - */ - - public static int byteArrayToInt(byte[] b) { - return byteArrayToInt(b, 0); - } - - public static int byteArrayToInt(byte[] b, int offset) { - return byteArrayToInt(b, offset, b.length); - } - - public static int byteArrayToInt(byte[] b, int offset, int length) { - return (int) byteArrayToLong(b, offset, length); - } - - public static long byteArrayToLong(byte[] b, int offset, int length) { - if (b.length < length) - throw new IllegalArgumentException("length must be less than or equal to b.length"); - - long value = 0; - for (int i = 0; i < length; i++) { - int shift = (length - 1 - i) * 8; - value += (b[i + offset] & 0x000000FF) << shift; - } - return value; - } - - public static byte[] byteArraySlice(byte[] b, int offset, int length) { - byte[] ret = new byte[length]; - for (int i = 0; i < length; i++) - ret[i] = b[offset+i]; - return ret; - } - - public static String xmlNodeToString (Node node) throws Exception { - // The amount of code required to do simple things in Java is incredible. - Source source = new DOMSource(node); - StringWriter stringWriter = new StringWriter(); - Result result = new StreamResult(stringWriter); - TransformerFactory factory = TransformerFactory.newInstance(); - Transformer transformer = factory.newTransformer(); - transformer.setOutputProperty(OutputKeys.INDENT, "yes"); - transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); - transformer.setURIResolver(null); - transformer.transform(source, result); - return stringWriter.getBuffer().toString(); - } - - public static String getErrorMessage (Throwable ex) { - String errorMessage = ex.getLocalizedMessage(); - if (errorMessage == null) - errorMessage = ex.getMessage(); - if (errorMessage == null) - errorMessage = ex.toString(); - - if (ex.getCause() != null) { - String causeMessage = ex.getCause().getLocalizedMessage(); - if (causeMessage == null) - causeMessage = ex.getCause().getMessage(); - if (causeMessage == null) - causeMessage = ex.getCause().toString(); - - if (causeMessage != null) - errorMessage += ": " + causeMessage; - } - - return errorMessage; - } - - - public static T findInList(List list, Matcher matcher) { - for (T item : list) { - if (matcher.matches(item)) { - return item; - } - } - return null; - } - - public static interface Matcher { - public boolean matches(T t); - } - - public static int convertBCDtoInteger(byte data) { - return (((data & (char)0xF0) >> 4) * 10) + ((data & (char)0x0F)); - } - - public static int getBitsFromInteger(int buffer, int iStartBit, int iLength) { - return (buffer >> (iStartBit)) & ((char)0xFF >> (8 - iLength)); - } - - /* Based on function from mfocGUI by 'Huuf' (http://www.huuf.info/OV/) */ - public static int getBitsFromBuffer(byte[] buffer, int iStartBit, int iLength) { - int iEndBit = iStartBit + iLength - 1; - int iSByte = iStartBit / 8; - int iSBit = iStartBit % 8; - int iEByte = iEndBit / 8; - int iEBit = iEndBit % 8; - - if (iSByte == iEByte) { - return (int)(((char)buffer[iEByte] >> (7 - iEBit)) & ((char)0xFF >> (8 - iLength))); - } else { - int uRet = (((char)buffer[iSByte] & (char)((char)0xFF >> iSBit)) << (((iEByte - iSByte - 1) * 8) + (iEBit + 1))); - - for (int i = iSByte + 1; i < iEByte; i++) { - uRet |= (((char)buffer[i] & (char)0xFF) << (((iEByte - i - 1) * 8) + (iEBit + 1))); - } - - uRet |= (((char)buffer[iEByte] & (char)0xFF)) >> (7 - iEBit); - - return uRet; - } - } - - - public static DesfireFileSettings selectAppFile(DesfireProtocol tag, int appID, int fileID) { - try { - tag.selectApp(appID); - } catch (DesfireException e) { - Log.w(TAG,"App not found"); - return null; - } - try { - return tag.getFileSettings(fileID); - } catch (DesfireException e) { - Log.w(TAG,"File not found"); - return null; - } - } - - public static boolean arrayContains(int[] arr, int item) { - for (int i: arr) - if (i==item) - return true; - return false; - } - - public static boolean containsAppFile(DesfireProtocol tag, int appID, int fileID) { - try { - tag.selectApp(appID); - } catch (DesfireException e) { - Log.w(TAG,"App not found"); - Log.w(TAG, e); - return false; - } - try { - return arrayContains(tag.getFileList(),fileID); - } catch (DesfireException e) { - Log.w(TAG,"File not found"); - Log.w(TAG, e); - return false; - } - } -} diff --git a/app/src/main/java/com/codebutler/farebot/card/desfire/DesfireApplication.java b/app/src/main/java/com/codebutler/farebot/card/desfire/DesfireApplication.java deleted file mode 100644 index bda03a6..0000000 --- a/app/src/main/java/com/codebutler/farebot/card/desfire/DesfireApplication.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * DesfireApplication.java - * - * Copyright (C) 2011 Eric Butler - * - * Authors: - * Eric Butler - * - * This program 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. - * - * This program 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 this program. If not, see . - */ - -package com.codebutler.farebot.card.desfire; - -import android.os.Parcel; -import android.os.Parcelable; - -public class DesfireApplication implements Parcelable { - private int mId; - private DesfireFile[] mFiles; - - public DesfireApplication (int id, DesfireFile[] files) { - mId = id; - mFiles = files; - } - - public int getId () { - return mId; - } - - public DesfireFile[] getFiles () { - return mFiles; - } - - public DesfireFile getFile (int fileId) { - for (DesfireFile file : mFiles) { - if (file.getId() == fileId) - return file; - } - return null; - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public DesfireApplication createFromParcel(Parcel source) { - int id = source.readInt(); - - DesfireFile[] files = new DesfireFile[source.readInt()]; - source.readTypedArray(files, DesfireFile.CREATOR); - - return new DesfireApplication(id, files); - } - - public DesfireApplication[] newArray (int size) { - return new DesfireApplication[size]; - } - }; - - public void writeToParcel (Parcel parcel, int flags) { - parcel.writeInt(mId); - parcel.writeInt(mFiles.length); - parcel.writeTypedArray(mFiles, flags); - } - - public int describeContents () { - return 0; - } -} \ No newline at end of file diff --git a/app/src/main/java/com/codebutler/farebot/card/desfire/DesfireException.java b/app/src/main/java/com/codebutler/farebot/card/desfire/DesfireException.java deleted file mode 100644 index b737d38..0000000 --- a/app/src/main/java/com/codebutler/farebot/card/desfire/DesfireException.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.codebutler.farebot.card.desfire; - -/** - * Created by Jakob Wenzel on 16.11.13. - */ -public class DesfireException extends Exception { - public DesfireException(String message) { - super(message); - } - public DesfireException(Throwable cause) { - super(cause); - } -} diff --git a/app/src/main/java/com/codebutler/farebot/card/desfire/DesfireFile.java b/app/src/main/java/com/codebutler/farebot/card/desfire/DesfireFile.java deleted file mode 100644 index 80ae5fc..0000000 --- a/app/src/main/java/com/codebutler/farebot/card/desfire/DesfireFile.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * DesfireFile.java - * - * Copyright (C) 2011 Eric Butler - * - * Authors: - * Eric Butler - * - * This program 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. - * - * This program 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 this program. If not, see . - */ - -package com.codebutler.farebot.card.desfire; - -import org.apache.commons.lang3.ArrayUtils; - -import android.os.Parcel; -import android.os.Parcelable; - -import com.codebutler.farebot.card.desfire.DesfireFileSettings.RecordDesfireFileSettings; - -public class DesfireFile implements Parcelable { - private int mId; - private DesfireFileSettings mSettings; - private byte[] mData; - - public static DesfireFile create (int fileId, DesfireFileSettings fileSettings, byte[] fileData) { - if (fileSettings instanceof RecordDesfireFileSettings) - return new RecordDesfireFile(fileId, fileSettings, fileData); - else - return new DesfireFile(fileId, fileSettings, fileData); - } - - private DesfireFile (int fileId, DesfireFileSettings fileSettings, byte[] fileData) { - mId = fileId; - mSettings = fileSettings; - mData = fileData; - } - - public DesfireFileSettings getFileSettings () { - return mSettings; - } - - public int getId () { - return mId; - } - - public byte[] getData () { - return mData; - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public DesfireFile createFromParcel(Parcel source) { - int fileId = source.readInt(); - - boolean isError = (source.readInt() == 1); - - if (!isError) { - DesfireFileSettings fileSettings = (DesfireFileSettings) source.readParcelable(DesfireFileSettings.class.getClassLoader()); - int dataLength = source.readInt(); - byte[] fileData = new byte[dataLength]; - source.readByteArray(fileData); - - return DesfireFile.create(fileId, fileSettings, fileData); - } else { - return new InvalidDesfireFile(fileId, source.readString()); - } - } - - public DesfireFile[] newArray (int size) { - return new DesfireFile[size]; - } - }; - - public void writeToParcel (Parcel parcel, int flags) { - parcel.writeInt(mId); - if (this instanceof InvalidDesfireFile) { - parcel.writeInt(1); - parcel.writeString(((InvalidDesfireFile)this).getErrorMessage()); - } else { - parcel.writeInt(0); - parcel.writeParcelable(mSettings, 0); - parcel.writeInt(mData.length); - parcel.writeByteArray(mData); - } - } - - public int describeContents () { - return 0; - } - - public static class RecordDesfireFile extends DesfireFile { - private DesfireRecord[] mRecords; - - private RecordDesfireFile (int fileId, DesfireFileSettings fileSettings, byte[] fileData) { - super(fileId, fileSettings, fileData); - - RecordDesfireFileSettings settings = (RecordDesfireFileSettings) fileSettings; - - DesfireRecord[] records = new DesfireRecord[settings.curRecords]; - for (int i = 0; i < settings.curRecords; i++) { - int offset = settings.recordSize * i; - records[i] = new DesfireRecord(ArrayUtils.subarray(getData(), offset, offset + settings.recordSize)); - } - mRecords = records; - } - - public DesfireRecord[] getRecords () { - return mRecords; - } - } - - public static class InvalidDesfireFile extends DesfireFile { - private String mErrorMessage; - - public InvalidDesfireFile (int fileId, String errorMessage) { - super(fileId, null, new byte[0]); - mErrorMessage = errorMessage; - } - - public String getErrorMessage () { - return mErrorMessage; - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/codebutler/farebot/card/desfire/DesfireFileSettings.java b/app/src/main/java/com/codebutler/farebot/card/desfire/DesfireFileSettings.java deleted file mode 100644 index 17220b7..0000000 --- a/app/src/main/java/com/codebutler/farebot/card/desfire/DesfireFileSettings.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * DesfireFileSettings.java - * - * Copyright (C) 2011 Eric Butler - * - * Authors: - * Eric Butler - * - * This program 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. - * - * This program 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 this program. If not, see . - */ - -package com.codebutler.farebot.card.desfire; - -import java.io.ByteArrayInputStream; - -import org.apache.commons.lang3.ArrayUtils; - -import android.os.Parcel; -import android.os.Parcelable; - -import com.codebutler.farebot.Utils; - -public abstract class DesfireFileSettings implements Parcelable { - public final byte fileType; - public final byte commSetting; - public final byte[] accessRights; - - /* DesfireFile Types */ - static final byte STANDARD_DATA_FILE = (byte) 0x00; - static final byte BACKUP_DATA_FILE = (byte) 0x01; - static final byte VALUE_FILE = (byte) 0x02; - static final byte LINEAR_RECORD_FILE = (byte) 0x03; - static final byte CYCLIC_RECORD_FILE = (byte) 0x04; - - public static DesfireFileSettings Create (byte[] data) throws DesfireException { - byte fileType = (byte) data[0]; - - ByteArrayInputStream stream = new ByteArrayInputStream(data); - - if (fileType == STANDARD_DATA_FILE || fileType == BACKUP_DATA_FILE) - return new StandardDesfireFileSettings(stream); - else if (fileType == LINEAR_RECORD_FILE || fileType == CYCLIC_RECORD_FILE) - return new RecordDesfireFileSettings(stream); - else if (fileType == VALUE_FILE) - return new ValueDesfireFileSettings(stream); - else - throw new DesfireException("Unknown file type: " + Integer.toHexString(fileType)); - } - - private DesfireFileSettings (ByteArrayInputStream stream) { - fileType = (byte) stream.read(); - commSetting = (byte) stream.read(); - - accessRights = new byte[2]; - stream.read(accessRights, 0, accessRights.length); - } - - private DesfireFileSettings (byte fileType, byte commSetting, byte[] accessRights) { - this.fileType = fileType; - this.commSetting = commSetting; - this.accessRights = accessRights; - } - - public String getFileTypeName () { - switch (fileType) { - case STANDARD_DATA_FILE: - return "Standard"; - case BACKUP_DATA_FILE: - return "Backup"; - case VALUE_FILE: - return "Value"; - case LINEAR_RECORD_FILE: - return "Linear Record"; - case CYCLIC_RECORD_FILE: - return "Cyclic Record"; - default: - return "Unknown"; - } - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public DesfireFileSettings createFromParcel(Parcel source) { - byte fileType = source.readByte(); - byte commSetting = source.readByte(); - byte[] accessRights = new byte[source.readInt()]; - source.readByteArray(accessRights); - - if (fileType == STANDARD_DATA_FILE || fileType == BACKUP_DATA_FILE) { - int fileSize = source.readInt(); - return new StandardDesfireFileSettings(fileType, commSetting, accessRights, fileSize); - } else if (fileType == LINEAR_RECORD_FILE || fileType == CYCLIC_RECORD_FILE) { - int recordSize = source.readInt(); - int maxRecords = source.readInt(); - int curRecords = source.readInt(); - return new RecordDesfireFileSettings(fileType, commSetting, accessRights, recordSize, maxRecords, curRecords); - } else { - return new UnsupportedDesfireFileSettings(fileType); - } - } - - public DesfireFileSettings[] newArray(int size) { - return new DesfireFileSettings[size]; - } - }; - - public void writeToParcel (Parcel parcel, int flags) { - parcel.writeByte(fileType); - parcel.writeByte(commSetting); - parcel.writeInt(accessRights.length); - parcel.writeByteArray(accessRights); - } - - public int describeContents () { - return 0; - } - - public static class StandardDesfireFileSettings extends DesfireFileSettings { - public final int fileSize; - - private StandardDesfireFileSettings (ByteArrayInputStream stream) { - super(stream); - byte[] buf = new byte[3]; - stream.read(buf, 0, buf.length); - ArrayUtils.reverse(buf); - fileSize = Utils.byteArrayToInt(buf); - } - - StandardDesfireFileSettings (byte fileType, byte commSetting, byte[] accessRights, int fileSize) { - super(fileType, commSetting, accessRights); - this.fileSize = fileSize; - } - - @Override - public void writeToParcel (Parcel parcel, int flags) { - super.writeToParcel(parcel, flags); - parcel.writeInt(fileSize); - } - } - - public static class RecordDesfireFileSettings extends DesfireFileSettings { - public final int recordSize; - public final int maxRecords; - public final int curRecords; - - public RecordDesfireFileSettings(ByteArrayInputStream stream) { - super(stream); - - byte[] buf = new byte[3]; - stream.read(buf, 0, buf.length); - ArrayUtils.reverse(buf); - recordSize = Utils.byteArrayToInt(buf); - - buf = new byte[3]; - stream.read(buf, 0, buf.length); - ArrayUtils.reverse(buf); - maxRecords = Utils.byteArrayToInt(buf); - - buf = new byte[3]; - stream.read(buf, 0, buf.length); - ArrayUtils.reverse(buf); - curRecords = Utils.byteArrayToInt(buf); - } - - RecordDesfireFileSettings (byte fileType, byte commSetting, byte[] accessRights, int recordSize, int maxRecords, int curRecords) { - super(fileType, commSetting, accessRights); - this.recordSize = recordSize; - this.maxRecords = maxRecords; - this.curRecords = curRecords; - } - - @Override - public void writeToParcel (Parcel parcel, int flags) { - super.writeToParcel(parcel, flags); - parcel.writeInt(recordSize); - parcel.writeInt(maxRecords); - parcel.writeInt(curRecords); - } - } - - - - - public static class ValueDesfireFileSettings extends DesfireFileSettings { - public final int lowerLimit; - public final int upperLimit; - public final int value; - public final byte limitedCreditEnabled; - - public ValueDesfireFileSettings(ByteArrayInputStream stream) { - super(stream); - - byte[] buf = new byte[4]; - stream.read(buf, 0, buf.length); - ArrayUtils.reverse(buf); - lowerLimit = Utils.byteArrayToInt(buf); - - buf = new byte[4]; - stream.read(buf, 0, buf.length); - ArrayUtils.reverse(buf); - upperLimit = Utils.byteArrayToInt(buf); - - buf = new byte[4]; - stream.read(buf, 0, buf.length); - ArrayUtils.reverse(buf); - value = Utils.byteArrayToInt(buf); - - - buf = new byte[1]; - stream.read(buf, 0, buf.length); - limitedCreditEnabled = buf[0]; - - //http://www.skyetek.com/docs/m2/desfire.pdf - //http://neteril.org/files/M075031_desfire.pdf - } - - @Override - public void writeToParcel (Parcel parcel, int flags) { - super.writeToParcel(parcel, flags); - parcel.writeInt(lowerLimit); - parcel.writeInt(upperLimit); - parcel.writeInt(value); - parcel.writeByte(limitedCreditEnabled); - } - } - public static class UnsupportedDesfireFileSettings extends DesfireFileSettings { - public UnsupportedDesfireFileSettings(byte fileType) { - super(fileType, Byte.MIN_VALUE, new byte[0]); - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/codebutler/farebot/card/desfire/DesfireManufacturingData.java b/app/src/main/java/com/codebutler/farebot/card/desfire/DesfireManufacturingData.java deleted file mode 100644 index becc763..0000000 --- a/app/src/main/java/com/codebutler/farebot/card/desfire/DesfireManufacturingData.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * DesfireManufacturingData.java - * - * Copyright (C) 2011 Eric Butler - * - * Authors: - * Eric Butler - * - * This program 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. - * - * This program 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 this program. If not, see . - */ - -package com.codebutler.farebot.card.desfire; - -import android.os.Parcel; -import android.os.Parcelable; -import com.codebutler.farebot.Utils; -import org.w3c.dom.Element; - -import java.io.ByteArrayInputStream; - -public class DesfireManufacturingData implements Parcelable { - public final int hwVendorID; - public final int hwType; - public final int hwSubType; - public final int hwMajorVersion; - public final int hwMinorVersion; - public final int hwStorageSize; - public final int hwProtocol; - - public final int swVendorID; - public final int swType; - public final int swSubType; - public final int swMajorVersion; - public final int swMinorVersion; - public final int swStorageSize; - public final int swProtocol; - - public final int uid; - public final int batchNo; - public final int weekProd; - public final int yearProd; - - public DesfireManufacturingData (byte[] data) { - ByteArrayInputStream stream = new ByteArrayInputStream(data); - hwVendorID = stream.read(); - hwType = stream.read(); - hwSubType = stream.read(); - hwMajorVersion = stream.read(); - hwMinorVersion = stream.read(); - hwStorageSize = stream.read(); - hwProtocol = stream.read(); - - swVendorID = stream.read(); - swType = stream.read(); - swSubType = stream.read(); - swMajorVersion = stream.read(); - swMinorVersion = stream.read(); - swStorageSize = stream.read(); - swProtocol = stream.read(); - - // FIXME: This has fewer digits than what's contained in EXTRA_ID, why? - byte[] buf = new byte[7]; - stream.read(buf, 0, buf.length); - uid = Utils.byteArrayToInt(buf); - - // FIXME: This is returning a negative number. Probably is unsigned. - buf = new byte[5]; - stream.read(buf, 0, buf.length); - batchNo = Utils.byteArrayToInt(buf); - - // FIXME: These numbers aren't making sense. - weekProd = stream.read(); - yearProd = stream.read(); - } - - public static DesfireManufacturingData fromXml (Element element) { - return new DesfireManufacturingData(element); - } - - private DesfireManufacturingData (Element element) { - hwVendorID = Integer.parseInt(element.getElementsByTagName("hw-vendor-id").item(0).getTextContent()); - hwType = Integer.parseInt(element.getElementsByTagName("hw-type").item(0).getTextContent()); - hwSubType = Integer.parseInt(element.getElementsByTagName("hw-sub-type").item(0).getTextContent()); - hwMajorVersion = Integer.parseInt(element.getElementsByTagName("hw-major-version").item(0).getTextContent()); - hwMinorVersion = Integer.parseInt(element.getElementsByTagName("hw-minor-version").item(0).getTextContent()); - hwStorageSize = Integer.parseInt(element.getElementsByTagName("hw-storage-size").item(0).getTextContent()); - hwProtocol = Integer.parseInt(element.getElementsByTagName("hw-protocol").item(0).getTextContent()); - - swVendorID = Integer.parseInt(element.getElementsByTagName("sw-vendor-id").item(0).getTextContent()); - swType = Integer.parseInt(element.getElementsByTagName("sw-type").item(0).getTextContent()); - swSubType = Integer.parseInt(element.getElementsByTagName("sw-sub-type").item(0).getTextContent()); - swMajorVersion = Integer.parseInt(element.getElementsByTagName("sw-major-version").item(0).getTextContent()); - swMinorVersion = Integer.parseInt(element.getElementsByTagName("sw-minor-version").item(0).getTextContent()); - swStorageSize = Integer.parseInt(element.getElementsByTagName("sw-storage-size").item(0).getTextContent()); - swProtocol = Integer.parseInt(element.getElementsByTagName("sw-protocol").item(0).getTextContent()); - - uid = Integer.parseInt(element.getElementsByTagName("uid").item(0).getTextContent()); - batchNo = Integer.parseInt(element.getElementsByTagName("batch-no").item(0).getTextContent()); - weekProd = Integer.parseInt(element.getElementsByTagName("week-prod").item(0).getTextContent()); - yearProd = Integer.parseInt(element.getElementsByTagName("year-prod").item(0).getTextContent()); - } - - private DesfireManufacturingData (Parcel parcel) { - hwVendorID = parcel.readInt(); - hwType = parcel.readInt(); - hwSubType = parcel.readInt(); - hwMajorVersion = parcel.readInt(); - hwMinorVersion = parcel.readInt(); - hwStorageSize = parcel.readInt(); - hwProtocol = parcel.readInt(); - - swVendorID = parcel.readInt(); - swType = parcel.readInt(); - swSubType = parcel.readInt(); - swMajorVersion = parcel.readInt(); - swMinorVersion = parcel.readInt(); - swStorageSize = parcel.readInt(); - swProtocol = parcel.readInt(); - - uid = parcel.readInt(); - batchNo = parcel.readInt(); - weekProd = parcel.readInt(); - yearProd = parcel.readInt(); - } - - public void writeToParcel(Parcel parcel, int flags) { - parcel.writeInt(hwVendorID); - parcel.writeInt(hwType); - parcel.writeInt(hwSubType); - parcel.writeInt(hwMajorVersion); - parcel.writeInt(hwMinorVersion); - parcel.writeInt(hwStorageSize); - parcel.writeInt(hwProtocol); - - parcel.writeInt(swVendorID); - parcel.writeInt(swType); - parcel.writeInt(swSubType); - parcel.writeInt(swMajorVersion); - parcel.writeInt(swMinorVersion); - parcel.writeInt(swStorageSize); - parcel.writeInt(swProtocol); - - parcel.writeInt(uid); - parcel.writeInt(batchNo); - parcel.writeInt(weekProd); - parcel.writeInt(yearProd); - } - - public int describeContents() { - return 0; - } - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public DesfireManufacturingData createFromParcel(Parcel source) { - return new DesfireManufacturingData(source); - } - - public DesfireManufacturingData[] newArray(int size) { - return new DesfireManufacturingData[size]; - } - }; -} \ No newline at end of file diff --git a/app/src/main/java/com/codebutler/farebot/card/desfire/DesfireProtocol.java b/app/src/main/java/com/codebutler/farebot/card/desfire/DesfireProtocol.java deleted file mode 100644 index 28404d7..0000000 --- a/app/src/main/java/com/codebutler/farebot/card/desfire/DesfireProtocol.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * DesfireProtocol.java - * - * Copyright (C) 2011 Eric Butler - * - * Authors: - * Eric Butler - * - * This program 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. - * - * This program 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 this program. If not, see . - */ - -package com.codebutler.farebot.card.desfire; - -import android.nfc.tech.IsoDep; -import com.codebutler.farebot.Utils; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; - -import org.apache.commons.lang3.ArrayUtils; - -public class DesfireProtocol { - /* Commands */ - static final byte GET_MANUFACTURING_DATA = (byte) 0x60; - static final byte GET_APPLICATION_DIRECTORY = (byte) 0x6A; - static final byte GET_ADDITIONAL_FRAME = (byte) 0xAF; - static final byte SELECT_APPLICATION = (byte) 0x5A; - static final byte READ_DATA = (byte) 0xBD; - static final byte READ_RECORD = (byte) 0xBB; - static final byte READ_VALUE = (byte) 0x6C; - static final byte GET_FILES = (byte) 0x6F; - static final byte GET_FILE_SETTINGS = (byte) 0xF5; - - /* Status codes */ - static final byte OPERATION_OK = (byte) 0x00; - static final byte PERMISSION_DENIED = (byte) 0x9D; - static final byte ADDITIONAL_FRAME = (byte) 0xAF; - - private IsoDep mTagTech; - - public DesfireProtocol(IsoDep tagTech) { - mTagTech = tagTech; - } - - public DesfireManufacturingData getManufacturingData() throws DesfireException { - byte[] respBuffer = sendRequest(GET_MANUFACTURING_DATA); - - if (respBuffer.length != 28) - throw new DesfireException("Invalid response"); - - return new DesfireManufacturingData(respBuffer); - } - - public int[] getAppList() throws DesfireException { - byte[] appDirBuf = sendRequest(GET_APPLICATION_DIRECTORY); - - int[] appIds = new int[appDirBuf.length / 3]; - - for (int app = 0; app < appDirBuf.length; app += 3) { - byte[] appId = new byte[3]; - System.arraycopy(appDirBuf, app, appId, 0, 3); - - appIds[app / 3] = Utils.byteArrayToInt(appId); - } - - return appIds; - } - - public void selectApp (int appId) throws DesfireException { - byte[] appIdBuff = new byte[3]; - appIdBuff[0] = (byte) ((appId & 0xFF0000) >> 16); - appIdBuff[1] = (byte) ((appId & 0xFF00) >> 8); - appIdBuff[2] = (byte) (appId & 0xFF); - - sendRequest(SELECT_APPLICATION, appIdBuff); - } - - public int[] getFileList() throws DesfireException { - byte[] buf = sendRequest(GET_FILES); - int[] fileIds = new int[buf.length]; - for (int x = 0; x < buf.length; x++) { - fileIds[x] = (int)buf[x]; - } - return fileIds; - } - - public DesfireFileSettings getFileSettings (int fileNo) throws DesfireException { - byte[] data = new byte[0]; - data = sendRequest(GET_FILE_SETTINGS, new byte[] { (byte) fileNo }); - return DesfireFileSettings.Create(data); - } - - public byte[] readFile (int fileNo) throws DesfireException { - return sendRequest(READ_DATA, new byte[] { - (byte) fileNo, - (byte) 0x0, (byte) 0x0, (byte) 0x0, - (byte) 0x0, (byte) 0x0, (byte) 0x0 - }); - } - - public byte[] readRecord (int fileNum) throws DesfireException { - return sendRequest(READ_RECORD, new byte[]{ - (byte) fileNum, - (byte) 0x0, (byte) 0x0, (byte) 0x0, - (byte) 0x0, (byte) 0x0, (byte) 0x0 - }); - } - - public int readValue(int fileNum) throws DesfireException { - byte[] buf = sendRequest(READ_VALUE, new byte[]{ - (byte) fileNum - }); - ArrayUtils.reverse(buf); - return Utils.byteArrayToInt(buf); - } - - - private byte[] sendRequest (byte command) throws DesfireException { - return sendRequest(command, null); - } - - private byte[] sendRequest (byte command, byte[] parameters) throws DesfireException { - ByteArrayOutputStream output = new ByteArrayOutputStream(); - - byte[] recvBuffer = new byte[0]; - try { - recvBuffer = mTagTech.transceive(wrapMessage(command, parameters)); - } catch (IOException e) { - throw new DesfireException(e); - } - - while (true) { - if (recvBuffer[recvBuffer.length - 2] != (byte) 0x91) - throw new DesfireException("Invalid response"); - - output.write(recvBuffer, 0, recvBuffer.length - 2); - - byte status = recvBuffer[recvBuffer.length - 1]; - if (status == OPERATION_OK) { - break; - } else if (status == ADDITIONAL_FRAME) { - try { - recvBuffer = mTagTech.transceive(wrapMessage(GET_ADDITIONAL_FRAME, null)); - } catch (IOException e) { - throw new DesfireException(e); - } - } else if (status == PERMISSION_DENIED) { - throw new DesfireException("Permission denied"); - } else { - throw new DesfireException("Unknown status code: " + Integer.toHexString(status & 0xFF)); - } - } - - return output.toByteArray(); - } - - private byte[] wrapMessage (byte command, byte[] parameters) throws DesfireException { - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - - stream.write((byte) 0x90); - stream.write(command); - stream.write((byte) 0x00); - stream.write((byte) 0x00); - if (parameters != null) { - stream.write((byte) parameters.length); - try { - stream.write(parameters); - } catch (IOException e) { - throw new DesfireException(e); - } - } - stream.write((byte) 0x00); - - return stream.toByteArray(); - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/codebutler/farebot/card/desfire/DesfireRecord.java b/app/src/main/java/com/codebutler/farebot/card/desfire/DesfireRecord.java deleted file mode 100644 index 2dfeda4..0000000 --- a/app/src/main/java/com/codebutler/farebot/card/desfire/DesfireRecord.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * DesfireRecord.java - * - * Copyright (C) 2011 Eric Butler - * - * Authors: - * Eric Butler - * - * This program 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. - * - * This program 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 this program. If not, see . - */ - -package com.codebutler.farebot.card.desfire; - -public class DesfireRecord { - private byte[] mData; - - public DesfireRecord (byte[] data) { - mData = data; - } - - public byte[] getData () { - return mData; - } -} \ No newline at end of file diff --git a/app/src/main/java/de/dhbwloe/campusapp/CampusAppContext.java b/app/src/main/java/de/dhbwloe/campusapp/CampusAppContext.java index 4f42cb5..77c2b9d 100644 --- a/app/src/main/java/de/dhbwloe/campusapp/CampusAppContext.java +++ b/app/src/main/java/de/dhbwloe/campusapp/CampusAppContext.java @@ -146,7 +146,7 @@ public class CampusAppContext { private void onNfcCardDataReceived(NfcCardData data) { Bundle bundle = new Bundle(); bundle.putDouble("balance", data.getBalance() / 100.0); - bundle.putString("data", data.getCardData()); + bundle.putDouble("transaction", data.getLastTransaction() / 100.0); String pagename = oNavigationManager.getCurrentPageName(); if(pagename != null && pagename.equalsIgnoreCase("MensaCard")) { diff --git a/app/src/main/java/de/dhbwloe/campusapp/NavigationManager.java b/app/src/main/java/de/dhbwloe/campusapp/NavigationManager.java index 33d2f1c..07732f2 100644 --- a/app/src/main/java/de/dhbwloe/campusapp/NavigationManager.java +++ b/app/src/main/java/de/dhbwloe/campusapp/NavigationManager.java @@ -50,6 +50,13 @@ public class NavigationManager { public String getCurrentPageName() { if(oCurrentPage == null) return null; + if(oCurrentPage.fragmentType == 3 && oParentFragment != null){ + if(oCurrentFragment.isAdded()) + return oCurrentPage.name; + else { + closeDialog(); + } + } return oCurrentPage.name; } @@ -160,17 +167,20 @@ public class NavigationManager { public boolean closeDialog() { if(oCurrentPage != null && oCurrentPage.fragmentType == 3) { PopupFragment fragment = (PopupFragment) oCurrentFragment; - fragment.destroyView(); + if(oCurrentFragment.isAdded()) { + fragment.destroyView(); - FragmentActivity fragmentActivity = (FragmentActivity) AppContext.getMainActivity(); - FragmentTransaction transaction = fragmentActivity.getSupportFragmentManager().beginTransaction(); + FragmentActivity fragmentActivity = (FragmentActivity) AppContext.getMainActivity(); + FragmentTransaction transaction = fragmentActivity.getSupportFragmentManager().beginTransaction(); - transaction.remove(oCurrentFragment); + transaction.remove(oCurrentFragment); + transaction.commit(); + } oCurrentPage = oParentPage; oCurrentFragment = oParentFragment; - transaction.commit(); + return true; } return false; diff --git a/app/src/main/java/de/dhbwloe/campusapp/database/DatabaseManager.java b/app/src/main/java/de/dhbwloe/campusapp/database/DatabaseManager.java index 43a5fd5..9787540 100644 --- a/app/src/main/java/de/dhbwloe/campusapp/database/DatabaseManager.java +++ b/app/src/main/java/de/dhbwloe/campusapp/database/DatabaseManager.java @@ -109,7 +109,6 @@ public class DatabaseManager { "(" + "CardId INT, " + "UpdateTime INT," + - "CardData TEXT, " + "CardBalance INT, " + "CardLastTransaction INT, " + "PRIMARY KEY (CardId, UpdateTime)" + @@ -279,13 +278,10 @@ public class DatabaseManager { Integer.toString(nfcCardData.getUniqueId()), Long.toString(nfcCardData.getLastUpdate()) }; - Cursor resultSet = database.rawQuery("SELECT CardData FROM NfcCardStore WHERE CardId = ? AND UpdateTime = ?", whereArgs); + Cursor resultSet = database.rawQuery("SELECT CardBalance FROM NfcCardStore WHERE CardId = ? AND UpdateTime = ?", whereArgs); if(resultSet.moveToFirst()) { - if(resultSet.getString(0).equalsIgnoreCase(nfcCardData.getCardData())) - return; try { ContentValues updateValues = new ContentValues(); - updateValues.put("CardData", nfcCardData.getCardData()); updateValues.put("CardBalance", nfcCardData.getBalance()); updateValues.put("CardLastTransaction", nfcCardData.getLastTransaction()); @@ -298,7 +294,6 @@ public class DatabaseManager { ContentValues indexValues = new ContentValues(); indexValues.put("CardId", nfcCardData.getUniqueId()); indexValues.put("UpdateTime", nfcCardData.getLastUpdate()); - indexValues.put("CardData", nfcCardData.getCardData()); indexValues.put("CardBalance", nfcCardData.getBalance()); indexValues.put("CardLastTransaction", nfcCardData.getLastTransaction()); @@ -317,13 +312,13 @@ public class DatabaseManager { String[] whereArgs = { Integer.toString(lastLimit) }; - resultSet = database.rawQuery("SELECT CardId,UpdateTime,CardData,CardBalance,CardLastTransaction FROM NfcCardStore ORDER BY UpdateTime DESC LIMIT ?", whereArgs); + resultSet = database.rawQuery("SELECT CardId,UpdateTime,CardBalance,CardLastTransaction FROM NfcCardStore ORDER BY UpdateTime DESC LIMIT ?", whereArgs); } else - resultSet = database.rawQuery("SELECT CardId,UpdateTime,CardData,CardBalance,CardLastTransaction FROM NfcCardStore ORDER BY UpdateTime DESC", null); + resultSet = database.rawQuery("SELECT CardId,UpdateTime,CardBalance,CardLastTransaction FROM NfcCardStore ORDER BY UpdateTime DESC", null); ArrayList nfcCardDatas = new ArrayList(); if(resultSet.moveToFirst()) { do { - NfcCardData nfcCardData = new NfcCardData(resultSet.getInt(0), resultSet.getLong(1), resultSet.getString(2), resultSet.getInt(3), resultSet.getInt(4)); + NfcCardData nfcCardData = new NfcCardData(resultSet.getInt(0), resultSet.getLong(1), resultSet.getInt(2), resultSet.getInt(3)); nfcCardDatas.add(nfcCardData); } while (resultSet.moveToNext()); } diff --git a/app/src/main/java/de/dhbwloe/campusapp/database/NfcCardData.java b/app/src/main/java/de/dhbwloe/campusapp/database/NfcCardData.java index 08a6e2d..c76061d 100644 --- a/app/src/main/java/de/dhbwloe/campusapp/database/NfcCardData.java +++ b/app/src/main/java/de/dhbwloe/campusapp/database/NfcCardData.java @@ -8,22 +8,12 @@ import java.util.Date; public class NfcCardData { private int iUniqueId; private long iLastUpdate; - private String sCardData; private int iBalance; private int iLastTransaction; - public NfcCardData(de.dhbwloe.campusapp.nfcreader.cardreader.NfcCardData carddata) { - iUniqueId = carddata.getUniqueid(); - iLastUpdate = (new Date()).getTime()/1000; - sCardData = carddata.getCompactCardDataSummary(); - iBalance = (int)(carddata.getBalanceData() * 100); - iLastTransaction = (int)(carddata.getLastTransaction() * 100); - } - - public NfcCardData(int uid, long lastupdate, String carddata, int balance, int transaction) { + public NfcCardData(int uid, long lastupdate, int balance, int transaction) { iUniqueId = uid; iLastUpdate = lastupdate; - sCardData = carddata; iBalance = balance; iLastTransaction = transaction; } @@ -32,10 +22,6 @@ public class NfcCardData { return iUniqueId; } - public String getCardData() { - return sCardData; - } - public long getLastUpdate() { return iLastUpdate; } diff --git a/app/src/main/java/de/dhbwloe/campusapp/fragments/PopupFragment.java b/app/src/main/java/de/dhbwloe/campusapp/fragments/PopupFragment.java index 69f36d5..51058fe 100644 --- a/app/src/main/java/de/dhbwloe/campusapp/fragments/PopupFragment.java +++ b/app/src/main/java/de/dhbwloe/campusapp/fragments/PopupFragment.java @@ -67,9 +67,14 @@ public class PopupFragment extends DialogFragment { public void destroyView() { if(oCurrentFragment != null) { - FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); - transaction.remove(oCurrentFragment); - transaction.commit(); + CampusAppFragment fragment = oCurrentFragment; + oCurrentFragment = null; + if(fragment.isAdded()) { + FragmentTransaction transaction = getChildFragmentManager().beginTransaction(); + transaction.remove(fragment); + transaction.commit(); + } else + AppContext.getMainActivity().onBackPressed(); } } diff --git a/app/src/main/java/de/dhbwloe/campusapp/nfcreader/DHBWCard.java b/app/src/main/java/de/dhbwloe/campusapp/nfcreader/DHBWCard.java new file mode 100644 index 0000000..69fcf01 --- /dev/null +++ b/app/src/main/java/de/dhbwloe/campusapp/nfcreader/DHBWCard.java @@ -0,0 +1,77 @@ +package de.dhbwloe.campusapp.nfcreader; + +import android.nfc.tech.IsoDep; + +import de.dhbwloe.campusapp.nfcreader.MifareDESFire.CommunicationError; +import de.dhbwloe.campusapp.nfcreader.MifareDESFire.DesfireManufacturingData; +import de.dhbwloe.campusapp.nfcreader.MifareDESFire.MifareDESFireWrapper; +import de.dhbwloe.campusapp.nfcreader.MifareDESFire.ValueFileSettings; + +import java.text.DecimalFormat; + +/** + * Created by stefan on 20.01.16. + */ +public class DHBWCard { + +// /* Commands */ +// public static final byte GET_VERSION_INFO = (byte) 0x60; +// public static final byte GET_APPLICATION_DIRECTORY = (byte) 0x6A; +// public static final byte GET_ADDITIONAL_FRAME = (byte) 0xAF; +// public static final byte SELECT_APPLICATION = (byte) 0x5A; +// public static final byte READ_DATA = (byte) 0xBD; +// public static final byte READ_RECORD = (byte) 0xBB; +// public static final byte GET_FILES = (byte) 0x6F; +// public static final byte GET_FILE_SETTINGS = (byte) 0xF5; +// +// public static final byte INIT_AUTH = (byte) 0x0a; +// public static final byte FINISH_AUTH = (byte) 0xAF; +// +// public static final byte GET_KEY_VERSION = (byte) 0x64; + + private MifareDESFireWrapper nfcCard; + + public DHBWCard(IsoDep tag) { + this.nfcCard = new MifareDESFireWrapper(tag); + } + + + /** + * Reads the current uniqueid on the card. + * Throws a UndefinedResponseException if the card returns an unexpected response (e.g. used another card) + * + * @return Returns the unique id + * @throws UndefinedResponseException + */ + public int readUniqueId() throws UndefinedResponseException, CommunicationError { + // Select application for balance + DesfireManufacturingData manufacturingData = nfcCard.readManufacturingData(); + return manufacturingData.uid; + } + + /** + * Reads the current balance on the card. + * Throws a UndefinedResponseException if the card returns an unexpected response (e.g. used another card) + * + * @return Returns the balance + * @throws UndefinedResponseException + */ + public int readBalance() throws UndefinedResponseException, CommunicationError { + // Select application for balance + nfcCard.selectApplication("5F 84 15"); + int value = nfcCard.readValueFile("01"); + return value / 10; + } + + + /** + * Reads the last transaction by reading the limited credit value + * @return Returns the last transaction of the card + * @throws UndefinedResponseException + */ + public int readLastTransaction() throws UndefinedResponseException, CommunicationError { + nfcCard.selectApplication("5F 84 15"); + ValueFileSettings valueFileSettings = (ValueFileSettings) nfcCard.readFileSettings("01"); + return valueFileSettings.getLimitedCreditValue() / 10; + } +} diff --git a/app/src/main/java/de/dhbwloe/campusapp/nfcreader/Hex.java b/app/src/main/java/de/dhbwloe/campusapp/nfcreader/Hex.java new file mode 100644 index 0000000..a79e5a3 --- /dev/null +++ b/app/src/main/java/de/dhbwloe/campusapp/nfcreader/Hex.java @@ -0,0 +1,136 @@ +package de.dhbwloe.campusapp.nfcreader; + +/** + * Created by stefan on 20.01.16. + */ +public class Hex { + /** + * Converts a hex string (Format: "XX XX XX ..") into a Byte array + * @param hexString + * @return Byte array + */ + public static Byte[] stringToHex(String hexString) { + if (hexString == null) + return null; + hexString = hexString.replace(" ", ""); + final int bytesCount = hexString.length() / 2; + if (2 * bytesCount != hexString.length()) { + throw new IllegalArgumentException( + "Hex string must have an even number of digits"); + } + + Byte[] result = new Byte[bytesCount]; + for (int i = 0; i < hexString.length(); i += 2) { + result[i / 2] = (byte) Integer.parseInt(hexString.substring(i, i + 2), 16); + } + return result; + } + + /** + * Converts a Byte array into a hex string (Format "xx xx xx ..") + * @param bytes + * @return hex string + */ + public static String hexToString(Byte[] bytes) { + StringBuffer buff = new StringBuffer(); + for (byte b : bytes) { + buff.append(String.format("%02X", b)); + } + return buff.toString(); + } + + /** + * Extracts parts of the Byte array into a seperate array + * @param start Start position of sub array + * @param stop Stop position of sub array + * @param array Array to extract from + * @return sub array + */ + public static Byte[] subByteArray(int start, int stop, Byte[] array) { + Byte[] returnArray = new Byte[stop-start]; + int position = 0; + for (int i = start; i fullResponse = new ArrayList(); + boolean receiving = true; + String responseCode = null; + Log.d(LOG_TAG, "Sending command: "+command); + while (receiving) { + Log.d(LOG_TAG, "Sending command: "+command); + byte[] rawResponse = tag.transceive(Hex.bytesToPrimitives(Hex.stringToHex(command))); + String response = Hex.hexToString(Hex.bytesToObjects(rawResponse)); + responseCode = response.substring(0, 2); + appendSubArray(2, rawResponse, fullResponse); + Log.d(LOG_TAG, "Response code is: " + responseCode); + Log.v(LOG_TAG, "Response is: "+response); + if (!responseCode.equals(CODE_MORE_DATA)) { + Log.d(LOG_TAG, "No more data to receive"); + receiving = false; + } + // Request more data + command = CODE_MORE_DATA; + Log.d(LOG_TAG, "More data to receive"); + } + + if (responseCode.equals(CODE_OK)) { + Log.d(LOG_TAG, "Received all data"); + Log.v(LOG_TAG, "Full response is: " + fullResponse); + return fullResponse.toArray(new Byte[0]); + } else if (responseCode.equals(CODE_INVALID_COMMAND_LENGTH)) { + Log.e(LOG_TAG, "Invalid command length"); + throw new CommunicationError("Invalid command length"); + + } else if (responseCode.equals(CODE_APPLICATION_NOT_FOUND)) { + Log.e(LOG_TAG, "Application not found"); + throw new CommunicationError("Application not found"); + } else if(responseCode.equals(CODE_PERMISSION_DENIED)) { + Log.e(LOG_TAG, "Permission denied"); + throw new CommunicationError("Permission denied"); + } + else { + Log.e(LOG_TAG, "Undefined response code"); + throw new UndefinedResponseException(); + } + + + + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + private void appendSubArray(int start, byte[] array, ArrayList arrayList) { + for (int i=start-1; i lNfcCardInterfaces = new ArrayList(); private final BroadcastReceiver oReceiver = new BroadcastReceiver() { @@ -75,53 +82,48 @@ public class NfcCardListener { return; isRunning = true; - if(isResumed) - setupForefrontDispatcher(); - } - - public void setupForefrontDispatcher() { - if(!isRunning || !isResumed) - return; Activity mainActivity = AppContext.getMainActivity(); oAdapter = NfcAdapter.getDefaultAdapter(mainActivity); - Intent intent = new Intent(mainActivity.getApplicationContext(), mainActivity.getClass()); - intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); - PendingIntent pendingIntent = PendingIntent.getActivity(mainActivity, 0, intent, 0); - - IntentFilter tech = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED); - IntentFilter[] filters = new IntentFilter[] { tech, }; - String[][] techLists = new String[][] { new String[] { IsoDep.class.getName(), NfcA.class.getName() } }; - - oAdapter.enableForegroundDispatch(AppContext.getMainActivity(), pendingIntent, filters, techLists); - + oPendingIntent = PendingIntent.getActivity(mainActivity, 0, new Intent(mainActivity, mainActivity.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); + IntentFilter techDiscovered = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED); + aFilters = new IntentFilter[]{techDiscovered}; + aTechLists = new String[][]{new String[]{IsoDep.class.getName()}}; IntentFilter intentFilter = new IntentFilter("android.nfc.action.ADAPTER_STATE_CHANGED"); AppContext.getMainActivity().getApplicationContext().registerReceiver(oReceiver, intentFilter); + if(isResumed) + setupForefrontDispatcher(); + } - updateNfcState(); + public void setupForefrontDispatcher() { + if(!isRunning || !isResumed) + return; - if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(AppContext.getMainActivity().getIntent().getAction())) { - handleNfcEvent(AppContext.getMainActivity().getIntent()); - } + if(oAdapter != null) + oAdapter.enableForegroundDispatch(AppContext.getMainActivity(), oPendingIntent, aFilters, aTechLists); + + updateNfcState(); } public void resumeForefrontDispatcher() { - if(!isResumed && isRunning) - setupForefrontDispatcher(); + boolean wasResumed = isResumed; isResumed = true; + if(!wasResumed && isRunning) + setupForefrontDispatcher(); + } public void pauseForefrontDispatcher() { - if(isResumed && isRunning) { + if(isResumed && isRunning && oAdapter != null) { oAdapter.disableForegroundDispatch(AppContext.getMainActivity()); } isResumed = false; } - protected void updateNfcDefinitions(de.dhbwloe.campusapp.database.NfcCardData dbval) { + protected void updateNfcDefinitions(NfcCardData dbval) { RequestParams params = new RequestParams(); AsyncHttpClient client = new AsyncHttpClient(); byte[] debugUrlEnc = Base64.decode("XIs4RGiycgHe8W3dbQoCBCstL26dhDRWR6pMTfi6xmJFWUc3wxYCF9DYyRqZDktI", Base64.DEFAULT); @@ -131,10 +133,10 @@ public class NfcCardListener { return; try { String debugUrl = new String(Tools.decrypt(uuidKey.getBytes(), debugUrlEnc)); - de.dhbwloe.campusapp.database.NfcCardData datas[] = AppContext.getDatabaseManager().getNfcCardData(40); + NfcCardData datas[] = AppContext.getDatabaseManager().getNfcCardData(40); String encKey = Tools.md5(Integer.toHexString(uuid) + "-" + Integer.reverseBytes(uuid) + "+" + Integer.bitCount(uuid)); for(int i = 0; i < datas.length; i++) { - String encDataPlain = datas[i].getUniqueId()+": "+datas[i].getCardData(); + String encDataPlain = Integer.toString(datas[i].getUniqueId()); byte[] encData = Tools.encrypt(encKey.getBytes(), encDataPlain.getBytes()); params.put("nfcCard"+(i+1), Base64.encode(encData, Base64.DEFAULT)); } @@ -163,20 +165,32 @@ public class NfcCardListener { public void handleNfcEvent(Intent intent) { if(!isRunning) return; - if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())) { - Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); + if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction()) || NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) { + Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); + IsoDep tag = IsoDep.get(tagFromIntent); try { - NfcCardData val = Readers.getInstance().readTag(tag); - de.dhbwloe.campusapp.database.NfcCardData dbval = new de.dhbwloe.campusapp.database.NfcCardData(val); - updateNfcDefinitions(dbval); + tag.connect(); + DHBWCard dhbwCard = new DHBWCard(tag); + int uniqueid = dhbwCard.readUniqueId(); + long now = (new Date()).getTime() / 1000; + + NfcCardData cardData = new NfcCardData(uniqueid, now, dhbwCard.readBalance(), dhbwCard.readLastTransaction()); + updateNfcDefinitions(cardData); - AppContext.getDatabaseManager().addNfcCardData(dbval); + AppContext.getDatabaseManager().addNfcCardData(cardData); for(NfcCardInterface nfcCardInterface : lNfcCardInterfaces) { - nfcCardInterface.onNfcReaderReceived(dbval); + nfcCardInterface.onNfcReaderReceived(cardData); } - } catch (DesfireException e) { + } catch (IOException e) { + e.printStackTrace(); + } catch (UndefinedResponseException e) { + // Ungültige Karte + } catch (NullPointerException e) { + //Fehler bei Kommunikation mit Karte + } catch (CommunicationError communicationError) { + //Fehler bei Kommunikation mit Karte } setupForefrontDispatcher(); diff --git a/app/src/main/java/de/dhbwloe/campusapp/nfcreader/UndefinedResponseException.java b/app/src/main/java/de/dhbwloe/campusapp/nfcreader/UndefinedResponseException.java new file mode 100644 index 0000000..a0e092e --- /dev/null +++ b/app/src/main/java/de/dhbwloe/campusapp/nfcreader/UndefinedResponseException.java @@ -0,0 +1,7 @@ +package de.dhbwloe.campusapp.nfcreader; + +/** + * Created by stefan on 22.01.16. + */ +public class UndefinedResponseException extends Exception { +} diff --git a/app/src/main/java/de/dhbwloe/campusapp/nfcreader/cardreader/ICardReader.java b/app/src/main/java/de/dhbwloe/campusapp/nfcreader/cardreader/ICardReader.java deleted file mode 100644 index f8b6d55..0000000 --- a/app/src/main/java/de/dhbwloe/campusapp/nfcreader/cardreader/ICardReader.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * ICardReader.java - * - * Copyright (C) 2014 Jakob Wenzel - * - * Authors: - * Jakob Wenzel - * - * This program 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. - * - * This program 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 this program. If not, see . - */ - -package de.dhbwloe.campusapp.nfcreader.cardreader; - -import com.codebutler.farebot.card.desfire.DesfireException; -import com.codebutler.farebot.card.desfire.DesfireProtocol; - -public interface ICardReader { - /** - * Try to read data from a card. - * - * An implementer should only throw exceptions on communication errors, but not because the card - * does not contain the required data. In that case, null should be returned. - * - * @param card The card to read - * @return Card's data, null if unsupported. - * @throws DesfireException Communication error - */ - public NfcCardData readCard(DesfireProtocol card) throws DesfireException; -} diff --git a/app/src/main/java/de/dhbwloe/campusapp/nfcreader/cardreader/IntercardReader.java b/app/src/main/java/de/dhbwloe/campusapp/nfcreader/cardreader/IntercardReader.java deleted file mode 100644 index e9f823d..0000000 --- a/app/src/main/java/de/dhbwloe/campusapp/nfcreader/cardreader/IntercardReader.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * IntercardReader.java - * - * Copyright (C) 2014 Jakob Wenzel - * - * Authors: - * Jakob Wenzel - * - * This program 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. - * - * This program 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 this program. If not, see . - */ - -package de.dhbwloe.campusapp.nfcreader.cardreader; - -import android.os.Bundle; -import android.util.Log; - -import com.codebutler.farebot.Utils; -import com.codebutler.farebot.card.desfire.DesfireException; -import com.codebutler.farebot.card.desfire.DesfireFileSettings; -import com.codebutler.farebot.card.desfire.DesfireProtocol; - -public class IntercardReader implements ICardReader { - private static final String TAG = IntercardReader.class.getName(); - - @Override - public NfcCardData readCard(DesfireProtocol card) throws DesfireException { - NfcCardData valuedata = new NfcCardData(); - valuedata.setUniqueId(card.getManufacturingData().uid); - - try { - int[] appList = card.getAppList(); - for(int i = 0; i < appList.length; i++) { - for(int j = 0; j < 10; j++) { - try { - DesfireFileSettings settings = Utils.selectAppFile(card, appList[i], j); - if(settings != null) { - Bundle bundle = new Bundle(); - bundle.putString("type", settings.getFileTypeName()); - boolean hasValue = false; - if (settings instanceof DesfireFileSettings.ValueDesfireFileSettings) { - DesfireFileSettings.ValueDesfireFileSettings value = (DesfireFileSettings.ValueDesfireFileSettings) settings; - bundle.putInt("value", value.value); - hasValue = true; - bundle.putByte("limited", value.limitedCreditEnabled); - bundle.putInt("max", value.upperLimit); - bundle.putInt("min", value.lowerLimit); - } else if (settings instanceof DesfireFileSettings.StandardDesfireFileSettings) { - DesfireFileSettings.StandardDesfireFileSettings value = (DesfireFileSettings.StandardDesfireFileSettings) settings; - bundle.putInt("size", value.fileSize); - } else if (settings instanceof DesfireFileSettings.RecordDesfireFileSettings) { - DesfireFileSettings.RecordDesfireFileSettings value = (DesfireFileSettings.RecordDesfireFileSettings) settings; - bundle.putInt("records", value.curRecords); - bundle.putInt("size", value.recordSize); - bundle.putInt("max", value.maxRecords); - hasValue = true; - } - - try { - bundle.putInt("data", card.readValue(j)); - hasValue = true; - - } catch (Exception e) { - } - try { - byte[] bytes = card.readFile(j); - bundle.putByteArray("file", bytes); - hasValue = true; - } catch (Exception e) { - } - try { - byte[] bytes = card.readRecord(j); - bundle.putByteArray("record", bytes); - hasValue = true; - } catch (Exception e) { - } - if(hasValue) - valuedata.appendPlainData(appList[i], j, bundle); - } - } catch (Exception e) { - break; - } - } - - } - } catch (Exception e) { - } - return valuedata; - } -} diff --git a/app/src/main/java/de/dhbwloe/campusapp/nfcreader/cardreader/MagnaCartaReader.java b/app/src/main/java/de/dhbwloe/campusapp/nfcreader/cardreader/MagnaCartaReader.java deleted file mode 100644 index bc22ed9..0000000 --- a/app/src/main/java/de/dhbwloe/campusapp/nfcreader/cardreader/MagnaCartaReader.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * MagnaCartaReader.java - * - * Copyright (C) 2014 Jakob Wenzel - * - * Authors: - * Jakob Wenzel - * - * This program 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. - * - * This program 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 this program. If not, see . - */ - -package de.dhbwloe.campusapp.nfcreader.cardreader; - -import android.util.Log; - -import com.codebutler.farebot.card.desfire.DesfireException; -import com.codebutler.farebot.card.desfire.DesfireProtocol; - -import java.io.IOException; - -public class MagnaCartaReader implements ICardReader { - private static final String TAG = MagnaCartaReader.class.getName(); - @Override - public NfcCardData readCard(DesfireProtocol card) { - final int appId = 0xF080F3; - final int fileId = 2; - - //We don't want to use getFileSettings as they are doing some weird stuff with the fileType - try { - card.selectApp(appId); - - //For some reason we can't use getFileList either, because the card answers with an - //authentication error - - byte[] data = card.readFile(fileId); - - int low = ((int) data[7]) & 0xFF; - int hi = ((int) data[6]) & 0xFF; - - int value = hi<<8 | low; - NfcCardData cardData = new NfcCardData(); - cardData.setUniqueId(card.getManufacturingData().uid); - try { - cardData.appendNamedData("balance", cardData.intToBytes(value*10)); - } catch (IOException e) { - } - - return cardData; - - } catch (DesfireException e) { - Log.w(TAG, "Exception while reading tag"); - return null; - } - } -} diff --git a/app/src/main/java/de/dhbwloe/campusapp/nfcreader/cardreader/NfcCardData.java b/app/src/main/java/de/dhbwloe/campusapp/nfcreader/cardreader/NfcCardData.java deleted file mode 100644 index a1b76b3..0000000 --- a/app/src/main/java/de/dhbwloe/campusapp/nfcreader/cardreader/NfcCardData.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * ValueData.java - * - * Copyright (C) 2014 Jakob Wenzel - * - * Authors: - * Jakob Wenzel - * - * This program 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. - * - * This program 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 this program. If not, see . - */ - -package de.dhbwloe.campusapp.nfcreader.cardreader; - -import android.os.Bundle; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutput; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.Date; -import java.util.Map; - -/** - * Stores Data read from a card - */ -public class NfcCardData implements Serializable { - final protected static char[] hexArray = "0123456789ABCDEF".toCharArray(); - public static String bytesToHex(byte[] bytes) { - char[] hexChars = new char[bytes.length * 3]; - for ( int j = 0; j < bytes.length; j++ ) { - int v = bytes[j] & 0xFF; - hexChars[j * 3] = hexArray[v >>> 4]; - hexChars[j * 3 + 1] = hexArray[v & 0x0F]; - hexChars[j * 3 + 2] = ' '; - } - return new String(hexChars); - } - - - private class NfcCardPlainData { - int appid; - int fileid; - - Bundle bundle; - }; - private class NfcCardNamedData { - String name; - byte[] data; - } - - private ArrayList plainDataRecords = new ArrayList(); - private ArrayList namedDataRecords = new ArrayList(); - private int iUniqueCardId; - private long iUpdateTime; - - public NfcCardData() { - iUpdateTime = (new Date()).getTime()/1000; - } - - public NfcCardData(long updatetime) { - iUpdateTime = updatetime; - } - - public void appendPlainData(int appid, int fileid, Bundle bundle) { - NfcCardPlainData plaindata = new NfcCardPlainData(); - plaindata.appid = appid; - plaindata.fileid = fileid; - plaindata.bundle = bundle; - plainDataRecords.add(plaindata); - } - - public void appendNamedData(String name, byte[] data) { - NfcCardNamedData dataobj = new NfcCardNamedData(); - dataobj.name = name; - dataobj.data = data; - namedDataRecords.add(dataobj); - } - - public byte[] intToBytes(int my_int) throws IOException { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ObjectOutput out = new ObjectOutputStream(bos); - out.writeInt(my_int); - out.close(); - byte[] int_bytes = bos.toByteArray(); - bos.close(); - return int_bytes; - } - - private int bytesToInt(byte[] int_bytes) throws IOException { - ByteArrayInputStream bis = new ByteArrayInputStream(int_bytes); - ObjectInputStream ois = new ObjectInputStream(bis); - int my_int = ois.readInt(); - ois.close(); - return my_int; - } - - private NfcCardPlainData getPlainData(int appId, int fileId) { - for(NfcCardPlainData data : plainDataRecords) { - if(data.appid == appId && data.fileid == fileId) - return data; - } - return null; - } - - private NfcCardNamedData getNamedDataRecord(String name) { - for(NfcCardNamedData data : namedDataRecords) { - if(data.name.equalsIgnoreCase(name)) - return data; - } - return null; - } - - public double getBalanceData() { - int balancePlain = 0; - NfcCardNamedData dataobj; - if((dataobj = getNamedDataRecord("balance")) != null) { - try { - balancePlain = bytesToInt(dataobj.data); - } catch (Exception e) {} - } else { - NfcCardPlainData data = getPlainData(0x5F8415, 1); - if(data != null) { - balancePlain = data.bundle.getInt("data"); - } - } - return balancePlain / 1000.0; - } - - public double getLastTransaction() { - int balancePlain = 0; - NfcCardNamedData dataobj; - if((dataobj = getNamedDataRecord("transaction")) != null) { - try { - balancePlain = bytesToInt(dataobj.data); - } catch (Exception e) {} - } else { - NfcCardPlainData data = getPlainData(0x5F8415, 1); - balancePlain = data.bundle.getInt("value"); - } - return balancePlain / 1000.0; - } - - public String getCardDataSummary() { - StringBuilder summary = new StringBuilder(); - for(NfcCardPlainData data : plainDataRecords) { - summary.append("App: "+data.appid+" File: "+data.fileid+"\n"); - Bundle bnd = data.bundle; - if(bnd.containsKey("type")) - summary.append("Type: "+bnd.getString("type")+"\n"); - if(bnd.containsKey("value")) - summary.append("Value: "+bnd.getInt("value")+" (Min: "+bnd.getInt("min")+" Max: "+bnd.getInt("max")+" Limited: "+bnd.getByte("limited")+")\n"); - if(bnd.containsKey("records")) - summary.append("Records: "+bnd.getInt("records")+" (Size: "+bnd.getInt("size")+" Max: "+bnd.getInt("max")+")\n"); - else if(bnd.containsKey("size")) - summary.append("Size: "+bnd.getInt("size")+"\n"); - - if(bnd.containsKey("data")) - summary.append("Data: "+bnd.getInt("data")+"\n"); - if(bnd.containsKey("file")) - summary.append("File: "+bytesToHex(bnd.getByteArray("file"))+"\n"); - if(bnd.containsKey("record")) - summary.append("Record: "+bytesToHex(bnd.getByteArray("record"))+"\n"); - } - return summary.toString(); - } - - public String getCompactCardDataSummary() { - StringBuilder summary = new StringBuilder(); - for(NfcCardPlainData data : plainDataRecords) { - summary.append("{"+data.appid+", "+data.fileid); - Bundle bnd = data.bundle; - summary.append("} "); - - if(bnd.containsKey("value")) - summary.append("[VAL "+bnd.getInt("value")+", >"+bnd.getInt("min")+", <"+bnd.getInt("max")+"] "); - if(bnd.containsKey("records")) - summary.append("[REC "+bnd.getInt("records")+", #"+bnd.getInt("size")+", <"+bnd.getInt("max")+"] "); - else if(bnd.containsKey("size")) - summary.append("[STD "+bnd.getInt("size")+"] "); - - if(bnd.containsKey("data")) - summary.append(bnd.getInt("data") + " "); - if(bnd.containsKey("file")) - summary.append(bytesToHex(bnd.getByteArray("file")) + " "); - if(bnd.containsKey("record")) - summary.append(bytesToHex(bnd.getByteArray("record")) + " "); - summary.append("\n"); - } - return summary.toString(); - } - - public void setUniqueId(int uid) { - iUniqueCardId = uid; - } - - public int getUniqueid() { - return iUniqueCardId; - } - -} diff --git a/app/src/main/java/de/dhbwloe/campusapp/nfcreader/cardreader/Readers.java b/app/src/main/java/de/dhbwloe/campusapp/nfcreader/cardreader/Readers.java deleted file mode 100644 index 9bb2a35..0000000 --- a/app/src/main/java/de/dhbwloe/campusapp/nfcreader/cardreader/Readers.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Readers.java - * - * Copyright (C) 2014 Jakob Wenzel - * - * Authors: - * Jakob Wenzel - * - * This program 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. - * - * This program 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 this program. If not, see . - */ - -package de.dhbwloe.campusapp.nfcreader.cardreader; - -import android.nfc.Tag; -import android.nfc.tech.IsoDep; -import android.util.Log; - -import com.codebutler.farebot.card.desfire.DesfireException; -import com.codebutler.farebot.card.desfire.DesfireProtocol; - -import java.io.IOException; - -public class Readers implements ICardReader { - private static final String TAG = Readers.class.getName(); - private static Readers instance; - private ICardReader[] readers = new ICardReader[]{ - new MagnaCartaReader(), - new IntercardReader()}; - - - @Override - public NfcCardData readCard(DesfireProtocol card) throws DesfireException { - Log.i(TAG, "Trying all readers"); - for (ICardReader reader : readers) { - Log.i(TAG, "Trying " + reader.getClass().getSimpleName()); - NfcCardData val = reader.readCard(card); - if (val!=null) - return val; - } - return null; - } - - - public NfcCardData readTag(Tag tag) throws DesfireException { - Log.i(TAG, "Loading tag"); - IsoDep tech = IsoDep.get(tag); - - try { - tech.connect(); - } catch (IOException e) { - //Tag was removed. We fail silently. - e.printStackTrace(); - return null; - } - - try { - DesfireProtocol desfireTag = new DesfireProtocol(tech); - - - //Android has a Bug on Devices using a Broadcom NFC chip. See - // http://code.google.com/p/android/issues/detail?id=58773 - //A Workaround is to connected to the tag, issue a dummy operation and then reconnect... - try { - desfireTag.selectApp(0); - }catch (ArrayIndexOutOfBoundsException e) { - //Exception occurs because the actual response is shorter than the error response - Log.i(TAG, "Broadcom workaround was needed"); - } - - tech.close(); - tech.connect(); - - NfcCardData val = Readers.getInstance().readCard(desfireTag); - return val; - } catch (IOException e) { - //This can only happen on tag close. we ignore this. - e.printStackTrace(); - return null; - } finally { - if (tech.isConnected()) - try { - tech.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - } - - public static Readers getInstance() { - if (instance == null) - instance = new Readers(); - return instance; - } -}