--- /dev/null
+package de.dhbwloe.campusapp.nfcreader.MifareDESFire;
+
+import android.nfc.tech.IsoDep;
+import android.util.Log;
+
+import de.dhbwloe.campusapp.nfcreader.Hex;
+import de.dhbwloe.campusapp.nfcreader.UndefinedResponseException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+/**
+ * Created by stefan on 21.01.16.
+ */
+public class MifareDESFireWrapper implements IsoDepWrapper {
+ public final static String CODE_OK = "00";
+ public final static String CODE_MORE_DATA = "AF";
+ public final static String CODE_PERMISSION_DENIED = "9D";
+ public final static String CODE_APPLICATION_NOT_FOUND = "A0";
+ public final static String CODE_INVALID_COMMAND_LENGTH = "7E";
+
+ private IsoDep tag;
+ public static final String LOG_TAG = "MifareDESFireWrapper";
+
+ //TODO: Add all desfire functionality
+
+ public MifareDESFireWrapper(IsoDep tag) {
+ this.tag = tag;
+ }
+
+ /**
+ * @param applicationID Application id in following Format: "AD 00 03" (3 Hex digits)
+ * @throws UndefinedResponseException Thrown when the tag returns an undefined response
+ */
+ public void selectApplication(String applicationID) throws UndefinedResponseException, CommunicationError {
+ sendCommand("5A " + applicationID);
+ }
+
+ /**
+ * @param fileId The file id
+ * @return Returns the value of the value file
+ * @throws UndefinedResponseException Thrown when the tag returns an undefined response
+ */
+ public int readValueFile(String fileId) throws UndefinedResponseException, CommunicationError {
+ return Hex.hexToInteger(Hex.reverseByteOrder(this.sendCommand("6C " + fileId)));
+ }
+
+ /**
+ * @param fileId The file id
+ * @return Returns the FileSettings
+ * @throws UndefinedResponseException Thrown when the tag returns an undefined response
+ */
+ public FileSettings readFileSettings(String fileId) throws UndefinedResponseException, CommunicationError {
+ Byte[] data = sendCommand("F5 "+fileId);
+ FileSettings fileSettings = ValueFileSettings.createByRawData(data);
+ //TODO: Changeme
+ return fileSettings;
+ }
+
+ /**
+ * @return Returns the DesfireManufacturingData
+ * @throws UndefinedResponseException Thrown when the tag returns an undefined response
+ */
+ public DesfireManufacturingData readManufacturingData() throws UndefinedResponseException, CommunicationError {
+ Byte[] data = sendCommand("60");
+
+ if (data.length != 28)
+ throw new UndefinedResponseException();
+
+ return new DesfireManufacturingData(Hex.bytesToPrimitives(data));
+ }
+
+ /**
+ * @param command Command to send to the tag (Format example: "AF 00 01 EF 01"
+ * @return
+ * @throws UndefinedResponseException
+ */
+ public Byte[] sendCommand(String command) throws UndefinedResponseException, CommunicationError {
+ connect();
+ try {
+ ArrayList<Byte> fullResponse = new ArrayList<Byte>();
+ 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<Byte> arrayList) {
+ for (int i=start-1; i<array.length; i++) {
+ arrayList.add(array[i]);
+ }
+ }
+
+ private void connect() {
+ if (!tag.isConnected())
+ try {
+ tag.connect();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+}