From 93f3297e2cdb2ee95e2e254bef2728631701ac57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Skj=C3=B8lberg?= Date: Mon, 3 Aug 2020 00:24:59 +0200 Subject: [PATCH] Delete wrapper resources, add library project --- build.gradle | 9 +- ...IsdoDepAdapter.java => IsoDepAdapter.java} | 6 +- .../service/AbstractBackgroundUsbService.java | 4 - .../skjolber/nfc/service/AbstractService.java | 9 +- .../service/BluetoothBackgroundService.java | 2 + .../src/main/AndroidManifest.xml | 4 +- .../hceclient/EchoHostApduService.java | 28 +- ...uServiceActivity.java => HceActivity.java} | 60 +- .../hceclient/HceInvokerActivity.java | 11 +- .../hceclient/HelloHostApduService.java | 147 ++++ .../hceclient/PreferencesActivity.java | 3 +- .../nfc/external/hceclient/Utils.java | 28 + .../src/main/res/layout/activity_main.xml | 2 +- .../src/main/res/menu/internal_invoker.xml | 2 +- .../src/main/res/menu/main.xml | 2 +- .../src/main/res/values/strings.xml | 7 +- .../xml/{apduservice.xml => echoservice.xml} | 4 +- .../src/main/res/xml/helloservice.xml | 11 + .../src/main/res/xml/preferences.xml | 27 +- .../src/main/res/layout/activity_main.xml | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 +- wrapper/build.gradle | 10 + .../github/skjolber/android/nfc/ApduList.aidl | 19 - .../skjolber/android/nfc/BeamShareData.aidl | 19 - .../skjolber/android/nfc/IAppCallback.aidl | 30 - .../github/skjolber/android/nfc/INfcDta.aidl | 34 - .../github/skjolber/android/nfc/INfcTag.aidl | 48 -- .../android/nfc/INfcUnlockHandler.aidl | 12 - .../android/nfc/ITagRemovedCallback.aidl | 9 - .../github/skjolber/android/nfc/TagImpl.aidl | 20 - .../skjolber/android/nfc/TechListParcel.aidl | 19 - .../android/nfc/TransceiveResult.aidl | 19 - .../android/nfc/cardemulation/AidGroup.aidl | 19 - .../nfc/cardemulation/ApduServiceInfo.aidl | 19 - .../nfc/cardemulation/NfcFServiceInfo.aidl | 19 - .../github/skjolber/android/nfc/ApduList.java | 11 - .../skjolber/android/nfc/ApduListImpl.java | 70 -- .../skjolber/android/nfc/BeamShareData.java | 68 -- .../skjolber/android/nfc/ErrorCodes.java | 111 --- .../skjolber/android/nfc/IntentConverter.java | 55 -- .../com/github/skjolber/android/nfc/Tag.java | 44 -- .../github/skjolber/android/nfc/TagImpl.java | 455 ------------- .../skjolber/android/nfc/TagWrapper.java | 53 -- .../skjolber/android/nfc/TechListParcel.java | 66 -- .../android/nfc/TransceiveResult.java | 92 --- .../android/nfc/tech/BasicTagTechnology.java | 12 - .../nfc/tech/BasicTagTechnologyImpl.java | 159 ----- .../skjolber/android/nfc/tech/IsoDep.java | 52 -- .../skjolber/android/nfc/tech/IsoDepImpl.java | 217 ------ .../android/nfc/tech/IsoDepWrapper.java | 66 -- .../android/nfc/tech/MifareClassic.java | 117 ---- .../android/nfc/tech/MifareClassicImpl.java | 636 ------------------ .../nfc/tech/MifareClassicWrapper.java | 130 ---- .../android/nfc/tech/MifareUltralight.java | 62 -- .../nfc/tech/MifareUltralightImpl.java | 280 -------- .../nfc/tech/MifareUltralightWrapper.java | 70 -- .../skjolber/android/nfc/tech/Ndef.java | 107 --- .../android/nfc/tech/NdefFormatable.java | 116 ---- .../android/nfc/tech/NdefFormatableImpl.java | 180 ----- .../nfc/tech/NdefFormattableWrapper.java | 49 -- .../skjolber/android/nfc/tech/NdefImpl.java | 364 ---------- .../android/nfc/tech/NdefWrapper.java | 79 --- .../skjolber/android/nfc/tech/NfcA.java | 53 -- .../skjolber/android/nfc/tech/NfcAImpl.java | 180 ----- .../android/nfc/tech/NfcAWrapper.java | 67 -- .../skjolber/android/nfc/tech/NfcB.java | 120 ---- .../skjolber/android/nfc/tech/NfcBImpl.java | 128 ---- .../android/nfc/tech/NfcBWrapper.java | 57 -- .../skjolber/android/nfc/tech/NfcBarcode.java | 115 ---- .../android/nfc/tech/NfcBarcodeImpl.java | 139 ---- .../android/nfc/tech/NfcBarcodeWrapper.java | 45 -- .../skjolber/android/nfc/tech/NfcF.java | 149 ---- .../skjolber/android/nfc/tech/NfcFImpl.java | 183 ----- .../android/nfc/tech/NfcFWrapper.java | 68 -- .../skjolber/android/nfc/tech/NfcV.java | 125 ---- .../skjolber/android/nfc/tech/NfcVImpl.java | 131 ---- .../android/nfc/tech/NfcVWrapper.java | 47 -- .../android/nfc/tech/TagTechnology.java | 204 ------ 78 files changed, 324 insertions(+), 5876 deletions(-) rename core/src/main/java/com/github/skjolber/nfc/hce/tech/mifare/{IsdoDepAdapter.java => IsoDepAdapter.java} (89%) rename examples/hostCardEmulationClient/src/main/java/com/github/skjolber/nfc/external/hceclient/{EchoHostAdpuServiceActivity.java => HceActivity.java} (70%) create mode 100644 examples/hostCardEmulationClient/src/main/java/com/github/skjolber/nfc/external/hceclient/HelloHostApduService.java rename examples/hostCardEmulationClient/src/main/res/xml/{apduservice.xml => echoservice.xml} (69%) create mode 100644 examples/hostCardEmulationClient/src/main/res/xml/helloservice.xml delete mode 100644 wrapper/src/main/aidl/com/github/skjolber/android/nfc/ApduList.aidl delete mode 100644 wrapper/src/main/aidl/com/github/skjolber/android/nfc/BeamShareData.aidl delete mode 100644 wrapper/src/main/aidl/com/github/skjolber/android/nfc/IAppCallback.aidl delete mode 100644 wrapper/src/main/aidl/com/github/skjolber/android/nfc/INfcDta.aidl delete mode 100644 wrapper/src/main/aidl/com/github/skjolber/android/nfc/INfcTag.aidl delete mode 100644 wrapper/src/main/aidl/com/github/skjolber/android/nfc/INfcUnlockHandler.aidl delete mode 100644 wrapper/src/main/aidl/com/github/skjolber/android/nfc/ITagRemovedCallback.aidl delete mode 100644 wrapper/src/main/aidl/com/github/skjolber/android/nfc/TagImpl.aidl delete mode 100644 wrapper/src/main/aidl/com/github/skjolber/android/nfc/TechListParcel.aidl delete mode 100644 wrapper/src/main/aidl/com/github/skjolber/android/nfc/TransceiveResult.aidl delete mode 100644 wrapper/src/main/aidl/com/github/skjolber/android/nfc/cardemulation/AidGroup.aidl delete mode 100644 wrapper/src/main/aidl/com/github/skjolber/android/nfc/cardemulation/ApduServiceInfo.aidl delete mode 100644 wrapper/src/main/aidl/com/github/skjolber/android/nfc/cardemulation/NfcFServiceInfo.aidl delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/ApduList.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/ApduListImpl.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/BeamShareData.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/ErrorCodes.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/IntentConverter.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/Tag.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/TagImpl.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/TagWrapper.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/TechListParcel.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/TransceiveResult.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/BasicTagTechnology.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/BasicTagTechnologyImpl.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/IsoDep.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/IsoDepImpl.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/IsoDepWrapper.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/MifareClassic.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/MifareClassicImpl.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/MifareClassicWrapper.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/MifareUltralight.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/MifareUltralightImpl.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/MifareUltralightWrapper.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/Ndef.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NdefFormatable.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NdefFormatableImpl.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NdefFormattableWrapper.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NdefImpl.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NdefWrapper.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcA.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcAImpl.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcAWrapper.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcB.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcBImpl.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcBWrapper.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcBarcode.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcBarcodeImpl.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcBarcodeWrapper.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcF.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcFImpl.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcFWrapper.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcV.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcVImpl.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcVWrapper.java delete mode 100644 wrapper/src/main/java/com/github/skjolber/android/nfc/tech/TagTechnology.java diff --git a/build.gradle b/build.gradle index 3b34659..4e6d149 100644 --- a/build.gradle +++ b/build.gradle @@ -3,10 +3,14 @@ buildscript { repositories { google() jcenter() + + maven { + url "https://oss.sonatype.org/content/repositories/snapshots/" + } } dependencies { - classpath 'com.android.tools.build:gradle:3.6.1' + classpath 'com.android.tools.build:gradle:4.0.1' } } @@ -37,6 +41,9 @@ configure(buildProjects()) { repositories { google() jcenter() + maven { + url "https://oss.sonatype.org/content/repositories/snapshots/" + } } } diff --git a/core/src/main/java/com/github/skjolber/nfc/hce/tech/mifare/IsdoDepAdapter.java b/core/src/main/java/com/github/skjolber/nfc/hce/tech/mifare/IsoDepAdapter.java similarity index 89% rename from core/src/main/java/com/github/skjolber/nfc/hce/tech/mifare/IsdoDepAdapter.java rename to core/src/main/java/com/github/skjolber/nfc/hce/tech/mifare/IsoDepAdapter.java index af6edba..8b7de31 100644 --- a/core/src/main/java/com/github/skjolber/nfc/hce/tech/mifare/IsdoDepAdapter.java +++ b/core/src/main/java/com/github/skjolber/nfc/hce/tech/mifare/IsoDepAdapter.java @@ -12,14 +12,14 @@ import org.nfctools.NfcException; -public class IsdoDepAdapter extends DefaultTechnology implements CommandTechnology { +public class IsoDepAdapter extends DefaultTechnology implements CommandTechnology { - protected static final String TAG = IsdoDepAdapter.class.getName(); + protected static final String TAG = IsoDepAdapter.class.getName(); private DESFireAdapter adapter; private boolean hostCardEmulation; - public IsdoDepAdapter(int slotNumber, IsoDepWrapper isoDep, boolean hostCardEmulation) { + public IsoDepAdapter(int slotNumber, IsoDepWrapper isoDep, boolean hostCardEmulation) { super(TagTechnology.ISO_DEP, slotNumber); this.adapter = new DESFireAdapter(isoDep, false); this.hostCardEmulation = hostCardEmulation; diff --git a/core/src/main/java/com/github/skjolber/nfc/service/AbstractBackgroundUsbService.java b/core/src/main/java/com/github/skjolber/nfc/service/AbstractBackgroundUsbService.java index 255a877..9daca65 100644 --- a/core/src/main/java/com/github/skjolber/nfc/service/AbstractBackgroundUsbService.java +++ b/core/src/main/java/com/github/skjolber/nfc/service/AbstractBackgroundUsbService.java @@ -59,10 +59,6 @@ public abstract class AbstractBackgroundUsbService extends AbstractService { private static final String TAG = AbstractBackgroundUsbService.class.getName(); - private static final String DESCRIPTOR = "android.nfc.INfcTag"; - private static final String CLASS = "android.nfc.INfcTag"; - - private static class Scanner extends Handler { private static final long USB_RESCAN_INTERVAL_STANDARD = 1000; diff --git a/core/src/main/java/com/github/skjolber/nfc/service/AbstractService.java b/core/src/main/java/com/github/skjolber/nfc/service/AbstractService.java index d97f686..08fab9f 100644 --- a/core/src/main/java/com/github/skjolber/nfc/service/AbstractService.java +++ b/core/src/main/java/com/github/skjolber/nfc/service/AbstractService.java @@ -14,13 +14,12 @@ import android.util.Log; import com.acs.smartcard.ReaderException; -import com.github.skjolber.nfc.command.ACRCommands; import com.github.skjolber.nfc.hce.INFcTagBinder; import com.github.skjolber.nfc.hce.resolve.TagProxyStore; import com.github.skjolber.nfc.hce.tech.TagTechnology; import com.github.skjolber.nfc.hce.tech.mifare.MifareClassicAdapter; import com.github.skjolber.nfc.hce.tech.mifare.MifareClassicTagFactory; -import com.github.skjolber.nfc.hce.tech.mifare.IsdoDepAdapter; +import com.github.skjolber.nfc.hce.tech.mifare.IsoDepAdapter; import com.github.skjolber.nfc.hce.tech.mifare.MifareDesfireTagFactory; import com.github.skjolber.nfc.hce.tech.mifare.MifareUltralightAdapter; import com.github.skjolber.nfc.hce.tech.mifare.MifareUltralightTagFactory; @@ -63,8 +62,6 @@ import java.util.ArrayList; import java.util.List; -import custom.java.CommandAPDU; - public abstract class AbstractService extends Service { @@ -189,7 +186,7 @@ protected void hce(int slotNumber, byte[] atr, IsoDepWrapper wrapper) { try { List technologies = new ArrayList(); technologies.add(new NfcAAdapter(slotNumber, wrapper, true)); - technologies.add(new IsdoDepAdapter(slotNumber, wrapper, true)); + technologies.add(new IsoDepAdapter(slotNumber, wrapper, true)); int serviceHandle = store.add(slotNumber, technologies); @@ -219,7 +216,7 @@ protected void desfire(int slotNumber, byte[] atr, IsoDepWrapper wrapper) { List technologies = new ArrayList(); technologies.add(new NfcAAdapter(slotNumber, wrapper, false)); - technologies.add(new IsdoDepAdapter(slotNumber, wrapper, false)); + technologies.add(new IsoDepAdapter(slotNumber, wrapper, false)); int serviceHandle = store.add(slotNumber, technologies); diff --git a/core/src/main/java/com/github/skjolber/nfc/service/BluetoothBackgroundService.java b/core/src/main/java/com/github/skjolber/nfc/service/BluetoothBackgroundService.java index 8a29034..fb89f4d 100644 --- a/core/src/main/java/com/github/skjolber/nfc/service/BluetoothBackgroundService.java +++ b/core/src/main/java/com/github/skjolber/nfc/service/BluetoothBackgroundService.java @@ -682,6 +682,7 @@ private static String getCardStatusString(int cardStatus) { return "The card status is unknown."; } + /* Get the Error string. */ private static String getErrorString(int errorCode) { if (errorCode == BluetoothReader.ERROR_SUCCESS) { @@ -733,6 +734,7 @@ public static String getResponseString(byte[] response, int errorCode) { return getErrorString(errorCode); } + @Override public void onDestroy() { Log.i(TAG, "Service destroyed"); diff --git a/examples/hostCardEmulationClient/src/main/AndroidManifest.xml b/examples/hostCardEmulationClient/src/main/AndroidManifest.xml index 9cbb3bd..36a9114 100644 --- a/examples/hostCardEmulationClient/src/main/AndroidManifest.xml +++ b/examples/hostCardEmulationClient/src/main/AndroidManifest.xml @@ -14,7 +14,7 @@ android:theme="@style/AppTheme" > + android:resource="@xml/echoservice" /> services; + + static { + services = new HashMap<>(); + services.put(EchoHostApduService.class, R.xml.echoservice); + services.put(HelloHostApduService.class, R.xml.helloservice); + } private boolean receiving = false; + private CardEmulation cardEmulation; private final BroadcastReceiver hostCardEmulationBroadcastReceiver = new BroadcastReceiver() { @@ -72,14 +85,17 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_main); - CardEmulation cardEmulation = CardEmulation.getInstance(NfcAdapter.getDefaultAdapter(this)); + cardEmulation = CardEmulation.getInstance(NfcAdapter.getDefaultAdapter(this)); - boolean defaultService = cardEmulation.isDefaultServiceForAid(new ComponentName(this, EchoHostApduService.class), EchoHostApduService.AID); + for (Map.Entry entry : services.entrySet()) { + String aid = Utils.parseAid(this, entry.getValue()); - if (!defaultService) { - Log.w(TAG, "Expected default service for AID " + EchoHostApduService.AID); + if (!cardEmulation.isDefaultServiceForAid(new ComponentName(this, entry.getKey()), aid)) { + Log.d(TAG, "This application is NOT the preferred service for aid " + aid); + } else { + Log.d(TAG, "This application is the preferred service for aid " + aid); + } } - Log.d(TAG, "Service AID is " + EchoHostApduService.AID); enableBroadcast(); @@ -112,6 +128,36 @@ public void onClick(DialogInterface dialog, int which) { show(dialog); } + @Override + protected void onResume() { + super.onResume(); + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + + // note: this will only work for a single HCE service + for (Map.Entry entry : services.entrySet()) { + boolean preferred = prefs.getBoolean(PreferencesActivity.PREFERENCE_HOST_CARD_EMULATION_PREFERENCE + "_" + entry.getKey().getSimpleName(), true); + + if(preferred) { + if (cardEmulation.setPreferredService(this, new ComponentName(this, entry.getKey()))) { + Log.d(TAG, "Set " + entry.getKey().getName() + " to be the preferred HCE service for this activity"); + } else { + Log.w(TAG, "Unable to set " + entry.getKey().getName() + " to be the preferred HCE service for this activity"); + } + } + } + } + + @Override + protected void onPause() { + super.onPause(); + + if(cardEmulation.unsetPreferredService(this)) { + Log.d(TAG, "Unset preferred service for " + getClass().getName()); + } else { + Log.d(TAG, "Unable to unset preferred service for " + getClass().getName()); + } + } @Override public boolean onCreateOptionsMenu(Menu menu) { diff --git a/examples/hostCardEmulationClient/src/main/java/com/github/skjolber/nfc/external/hceclient/HceInvokerActivity.java b/examples/hostCardEmulationClient/src/main/java/com/github/skjolber/nfc/external/hceclient/HceInvokerActivity.java index 68ce11d..8a639dd 100644 --- a/examples/hostCardEmulationClient/src/main/java/com/github/skjolber/nfc/external/hceclient/HceInvokerActivity.java +++ b/examples/hostCardEmulationClient/src/main/java/com/github/skjolber/nfc/external/hceclient/HceInvokerActivity.java @@ -135,7 +135,16 @@ public void onTagDiscovered(Tag tag) { // attempt to select demo HCE application using iso adpu String isoApplicationString = prefs.getString(PreferencesActivity.PREFERENCE_HOST_CARD_EMULATION_ISO_APPLICATION_ID, null); // clean whitespace - isoApplicationString = isoApplicationString.replaceAll("\\s",""); + if(isoApplicationString != null) { + isoApplicationString = isoApplicationString.replaceAll("\\s", ""); + if(isoApplicationString.isEmpty()) { + isoApplicationString = null; + } + } + + if(isoApplicationString == null) { + isoApplicationString = Utils.parseAid(this, R.xml.echoservice); + } byte[] key = hexStringToByteArray(isoApplicationString); diff --git a/examples/hostCardEmulationClient/src/main/java/com/github/skjolber/nfc/external/hceclient/HelloHostApduService.java b/examples/hostCardEmulationClient/src/main/java/com/github/skjolber/nfc/external/hceclient/HelloHostApduService.java new file mode 100644 index 0000000..2ee4fbf --- /dev/null +++ b/examples/hostCardEmulationClient/src/main/java/com/github/skjolber/nfc/external/hceclient/HelloHostApduService.java @@ -0,0 +1,147 @@ +package com.github.skjolber.nfc.external.hceclient; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.nfc.cardemulation.HostApduService; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.util.Log; + +import com.github.skjolber.nfc.util.Broadcast; +import com.github.skjolber.nfc.util.CommandAPDU; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +/** + * + * Hello HCE service. + * + */ + +public class HelloHostApduService extends HostApduService { + + public final static int ISO_SELECT_APPLICATION = 0xA4;// + public final static int SELECT_APPLICATION = 0x5A;// + public static final byte OPERATION_OK = (byte)0x00; + public static final byte APPL_INTEGRITY_ERROR = (byte)0xA1; + + private static String TAG = HelloHostApduService.class.getName(); + + protected Broadcast broadcast = new Broadcast(this); + + @Override + public void onCreate() { + super.onCreate(); + Log.d(TAG, getClass().getName() + " HCE service created"); + } + + @Override + public byte[] processCommandApdu(byte[] request, Bundle extras) { + Log.d(TAG, "Process command ADPU " + toHexString(request)); + + CommandAPDU command = new CommandAPDU(request); + int ins = command.getINS(); + + if(extras != null) { + for (String s : extras.keySet()) { + Log.d(TAG, "Got extras " + s + ": " + extras.get(s)); + } + } + + byte[] response = response(OPERATION_OK, String.format("Hello operation %02X", ins).getBytes(StandardCharsets.UTF_8)); + if(ins == ISO_SELECT_APPLICATION || ins == SELECT_APPLICATION) { + String application = toHexString(command.getData(), 1, 3); + + Log.i(TAG, "Selected Application " + application); + + response = response(OPERATION_OK, new byte[]{0x03, 0x04, 0x05}); + } else { + Log.i(TAG, "Received unknown command " + String.format("0x%08X", ins)); + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + + boolean pingPong = prefs.getBoolean(PreferencesActivity.PREFERENCE_HOST_CARD_EMULATION_PING_PONG, true); + + if (pingPong) { + if (PingPong.isPing(request)) { + // respond with pong + Log.d(TAG, "Detected ping command, respond with pong"); + + return PingPong.getPong(); + } + } + } + + Intent intent = new Intent(this, HceActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.setAction(Broadcast.HOST_CARD_EMULATION_ACTION_PROCESS_COMMAND_ADPU); + + intent.putExtra(Broadcast.HOST_CARD_EMULATION_EXTRA_COMMAND, request); + intent.putExtra(Broadcast.HOST_CARD_EMULATION_EXTRA_RESPONSE, request); + + startActivity(intent); + + Intent b = new Intent(); + b.setAction(Broadcast.HOST_CARD_EMULATION_ACTION_PROCESS_COMMAND_ADPU); + b.putExtra(Broadcast.HOST_CARD_EMULATION_EXTRA_COMMAND, request); + b.putExtra(Broadcast.HOST_CARD_EMULATION_EXTRA_RESPONSE, response); + + broadcast.sendBroadcast(b); + + return response; + } + + public byte[] response(byte command, byte[] contents) { + try { + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + bout.write(contents); + bout.write(0x91); + bout.write(command); + return bout.toByteArray(); + } catch (IOException e) { + throw new RuntimeException(); + } + } + + private byte[] response(byte command) { + return new byte[]{(byte) 0x91, command}; + } + + @Override + public void onDeactivated(int reason) { + Log.i(TAG, "Deactivated: " + reason); + + broadcast.broadcast(Broadcast.HOST_CARD_EMULATION_ACTION_DEACTIVATED); + } + + /** + * Converts the byte array to HEX string. + * + * @param buffer + * the buffer. + * @return the HEX string. + */ + public static String toHexString(byte[] buffer) { + return toHexString(buffer, 0, buffer.length); + } + + + /** + * Converts the byte array to HEX string. + * + * @param buffer + * the buffer. + * @return the HEX string. + */ + public static String toHexString(byte[] buffer, int offset, int length) { + StringBuilder sb = new StringBuilder(); + for(int i = offset; i < offset + length; i++) { + byte b = buffer[i]; + sb.append(String.format("%02x", b&0xff)); + } + return sb.toString().toUpperCase(); + } + +} \ No newline at end of file diff --git a/examples/hostCardEmulationClient/src/main/java/com/github/skjolber/nfc/external/hceclient/PreferencesActivity.java b/examples/hostCardEmulationClient/src/main/java/com/github/skjolber/nfc/external/hceclient/PreferencesActivity.java index 0cac617..dddcfe5 100644 --- a/examples/hostCardEmulationClient/src/main/java/com/github/skjolber/nfc/external/hceclient/PreferencesActivity.java +++ b/examples/hostCardEmulationClient/src/main/java/com/github/skjolber/nfc/external/hceclient/PreferencesActivity.java @@ -22,7 +22,8 @@ public class PreferencesActivity extends Activity implements OnSharedPreferenceC public static final String PREFERENCE_HOST_CARD_EMULATION_PING_PONG = "preference_host_card_emulation_ping_pong"; public static final String PREFERENCE_HOST_CARD_EMULATION_ISO_APPLICATION_ID = "preference_host_card_emulation_iso_application_id"; - + public static final String PREFERENCE_HOST_CARD_EMULATION_PREFERENCE = "preference_host_card_emulation_preference"; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); diff --git a/examples/hostCardEmulationClient/src/main/java/com/github/skjolber/nfc/external/hceclient/Utils.java b/examples/hostCardEmulationClient/src/main/java/com/github/skjolber/nfc/external/hceclient/Utils.java index 4b78f51..00d9514 100644 --- a/examples/hostCardEmulationClient/src/main/java/com/github/skjolber/nfc/external/hceclient/Utils.java +++ b/examples/hostCardEmulationClient/src/main/java/com/github/skjolber/nfc/external/hceclient/Utils.java @@ -2,6 +2,11 @@ import android.app.Activity; import android.content.res.Resources; +import android.content.res.XmlResourceParser; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -11,6 +16,29 @@ public class Utils { private static String TAG = Utils.class.getName(); + public static String parseAid(Activity a, int resource) { + XmlPullParserFactory parserFactory; + try (XmlResourceParser parser = a.getResources().getXml(resource)) { + int eventType; + do { + eventType = parser.next(); + if(eventType == XmlPullParser.START_TAG) { + if(parser.getName().equals("aid-filter")) { + for(int i = 0; i < parser.getAttributeCount(); i++) { + if(parser.getAttributeName(i).equals("name")) { + return parser.getAttributeValue(i); + } + } + } + } + } while(eventType != XmlPullParser.END_DOCUMENT); + + throw new IllegalArgumentException("No aid-filter found"); + } catch (Exception e) { + throw new IllegalArgumentException(e); + } + } + public static byte[] getResource(int r, Activity a) throws IOException { Resources res = a.getResources(); InputStream in = res.openRawResource(r); diff --git a/examples/hostCardEmulationClient/src/main/res/layout/activity_main.xml b/examples/hostCardEmulationClient/src/main/res/layout/activity_main.xml index 1b0daa1..b6af0cb 100644 --- a/examples/hostCardEmulationClient/src/main/res/layout/activity_main.xml +++ b/examples/hostCardEmulationClient/src/main/res/layout/activity_main.xml @@ -6,7 +6,7 @@ android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" - tools:context="com.github.skjolber.nfc.external.hceclient.EchoHostAdpuServiceActivity" + tools:context="com.github.skjolber.nfc.external.hceclient.HceActivity" android:orientation="vertical" > - + tools:context="com.github.skjolber.nfc.external.hceclient.HceActivity" >- diff --git a/examples/hostCardEmulationClient/src/main/res/menu/main.xml b/examples/hostCardEmulationClient/src/main/res/menu/main.xml index 4ae289f..98b305e 100644 --- a/examples/hostCardEmulationClient/src/main/res/menu/main.xml +++ b/examples/hostCardEmulationClient/src/main/res/menu/main.xml @@ -1,6 +1,6 @@ - + tools:context="com.github.skjolber.nfc.external.hceclient.HceActivity" >- External NFC HCE Client - External NFC AID + Echo service + Hello service HCE client Preferences @@ -27,6 +28,10 @@ HCE Invoker: This simple activity will attempt to trigger the HCE service on another device (with the same app as this) for Android-to-Android two-way communications. So upon connection it will send an AID so that the correct application is invoked. Close + Hello HCE service preference + Use the CardEmulation.setPreference(..) when activity is active + Echo HCE service preference + Use the CardEmulation.setPreference(..) when activity is active diff --git a/examples/hostCardEmulationClient/src/main/res/xml/apduservice.xml b/examples/hostCardEmulationClient/src/main/res/xml/echoservice.xml similarity index 69% rename from examples/hostCardEmulationClient/src/main/res/xml/apduservice.xml rename to examples/hostCardEmulationClient/src/main/res/xml/echoservice.xml index a8fe98c..5610cf6 100644 --- a/examples/hostCardEmulationClient/src/main/res/xml/apduservice.xml +++ b/examples/hostCardEmulationClient/src/main/res/xml/echoservice.xml @@ -4,8 +4,8 @@ - + android:description="@string/echoServiceDescription" > + \ No newline at end of file diff --git a/examples/hostCardEmulationClient/src/main/res/xml/helloservice.xml b/examples/hostCardEmulationClient/src/main/res/xml/helloservice.xml new file mode 100644 index 0000000..d941522 --- /dev/null +++ b/examples/hostCardEmulationClient/src/main/res/xml/helloservice.xml @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/examples/hostCardEmulationClient/src/main/res/xml/preferences.xml b/examples/hostCardEmulationClient/src/main/res/xml/preferences.xml index cf2d32c..68822b3 100644 --- a/examples/hostCardEmulationClient/src/main/res/xml/preferences.xml +++ b/examples/hostCardEmulationClient/src/main/res/xml/preferences.xml @@ -2,14 +2,12 @@ - + + android:dialogTitle="@string/preferenceHostCardEmulationApplicationIdTitle" + android:key="preference_host_card_emulation_iso_application_id" + android:summary="@string/preferenceHostCardEmulationApplicationIdSummary" + android:title="@string/preferenceHostCardEmulationApplicationIdTitle" /> + + + + + \ No newline at end of file diff --git a/examples/nxpClient/src/main/res/layout/activity_main.xml b/examples/nxpClient/src/main/res/layout/activity_main.xml index c034b4d..3103120 100644 --- a/examples/nxpClient/src/main/res/layout/activity_main.xml +++ b/examples/nxpClient/src/main/res/layout/activity_main.xml @@ -6,7 +6,7 @@ android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" - tools:context="com.github.skjolber.nfc.external.hceclient.EchoHostAdpuServiceActivity" + tools:context="com.github.skjolber.nfc.external.hceclient.HceActivity" android:orientation="vertical" > get(); -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/ApduListImpl.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/ApduListImpl.java deleted file mode 100644 index ecd179f..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/ApduListImpl.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.github.skjolber.android.nfc; - -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.ArrayList; -import java.util.List; - -/** - * @hide - */ -public class ApduListImpl implements ApduList { - - private ArrayList commands = new ArrayList(); - - public ApduListImpl() { - } - - @Override - public void add(byte[] command) { - commands.add(command); - } - - @Override - public List get() { - return commands; - } - - public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - @Override - public ApduList createFromParcel(Parcel in) { - return new ApduListImpl(in); - } - - @Override - public ApduList[] newArray(int size) { - return new ApduList[size]; - } - }; - - private ApduListImpl(Parcel in) { - int count = in.readInt(); - - for (int i = 0 ; i < count ; i++) { - - int length = in.readInt(); - byte[] cmd = new byte[length]; - in.readByteArray(cmd); - commands.add(cmd); - } - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(commands.size()); - - for (byte[] cmd : commands) { - dest.writeInt(cmd.length); - dest.writeByteArray(cmd); - } - } -} - - diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/BeamShareData.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/BeamShareData.java deleted file mode 100644 index 128a3a4..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/BeamShareData.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.github.skjolber.android.nfc; - -import android.net.Uri; -import android.nfc.NdefMessage; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.UserHandle; - -/** - * Class to IPC data to be shared over Android Beam. - * Allows bundling NdefMessage, Uris and flags in a single - * IPC call. This is important as we want to reduce the - * amount of IPC calls at "touch time". - * @hide - */ -public class BeamShareData implements Parcelable { - public final NdefMessage ndefMessage; - public final Uri[] uris; - public final UserHandle userHandle; - public final int flags; - - public BeamShareData(NdefMessage msg, Uri[] uris, UserHandle userHandle, int flags) { - this.ndefMessage = msg; - this.uris = uris; - this.userHandle = userHandle; - this.flags = flags; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - int urisLength = (uris != null) ? uris.length : 0; - dest.writeParcelable(ndefMessage, 0); - dest.writeInt(urisLength); - if (urisLength > 0) { - dest.writeTypedArray(uris, 0); - } - dest.writeParcelable(userHandle, 0); - dest.writeInt(this.flags); - } - - public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - @Override - public BeamShareData createFromParcel(Parcel source) { - Uri[] uris = null; - NdefMessage msg = source.readParcelable(NdefMessage.class.getClassLoader()); - int numUris = source.readInt(); - if (numUris > 0) { - uris = new Uri[numUris]; - source.readTypedArray(uris, Uri.CREATOR); - } - UserHandle userHandle = source.readParcelable(UserHandle.class.getClassLoader()); - int flags = source.readInt(); - - return new BeamShareData(msg, uris, userHandle, flags); - } - - @Override - public BeamShareData[] newArray(int size) { - return new BeamShareData[size]; - } - }; -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/ErrorCodes.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/ErrorCodes.java deleted file mode 100644 index b25ebf4..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/ErrorCodes.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2010, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.github.skjolber.android.nfc; - - -/** - * This class defines all the error codes that can be returned by the service - * and producing an exception on the application level. These are needed since - * binders does not support exceptions. - * - */ -public class ErrorCodes { - - public static boolean isError(int code) { - if (code < 0) { - return true; - } else { - return false; - } - } - - public static String asString(int code) { - switch (code) { - case SUCCESS: return "SUCCESS"; - case ERROR_IO: return "IO"; - case ERROR_CANCELLED: return "CANCELLED"; - case ERROR_TIMEOUT: return "TIMEOUT"; - case ERROR_BUSY: return "BUSY"; - case ERROR_CONNECT: return "CONNECT/DISCONNECT"; -// case ERROR_DISCONNECT: return "DISCONNECT"; - case ERROR_READ: return "READ"; - case ERROR_WRITE: return "WRITE"; - case ERROR_INVALID_PARAM: return "INVALID_PARAM"; - case ERROR_INSUFFICIENT_RESOURCES: return "INSUFFICIENT_RESOURCES"; - case ERROR_SOCKET_CREATION: return "SOCKET_CREATION"; - case ERROR_SOCKET_NOT_CONNECTED: return "SOCKET_NOT_CONNECTED"; - case ERROR_BUFFER_TO_SMALL: return "BUFFER_TO_SMALL"; - case ERROR_SAP_USED: return "SAP_USED"; - case ERROR_SERVICE_NAME_USED: return "SERVICE_NAME_USED"; - case ERROR_SOCKET_OPTIONS: return "SOCKET_OPTIONS"; - case ERROR_NFC_ON: return "NFC_ON"; - case ERROR_NOT_INITIALIZED: return "NOT_INITIALIZED"; - case ERROR_SE_ALREADY_SELECTED: return "SE_ALREADY_SELECTED"; - case ERROR_SE_CONNECTED: return "SE_CONNECTED"; - case ERROR_NO_SE_CONNECTED: return "NO_SE_CONNECTED"; - case ERROR_NOT_SUPPORTED: return "NOT_SUPPORTED"; - default: return "UNKNOWN ERROR"; - } - } - - public static final int SUCCESS = 0; - - public static final int ERROR_IO = -1; - - public static final int ERROR_CANCELLED = -2; - - public static final int ERROR_TIMEOUT = -3; - - public static final int ERROR_BUSY = -4; - - public static final int ERROR_CONNECT = -5; - - public static final int ERROR_DISCONNECT = -5; - - public static final int ERROR_READ = -6; - - public static final int ERROR_WRITE = -7; - - public static final int ERROR_INVALID_PARAM = -8; - - public static final int ERROR_INSUFFICIENT_RESOURCES = -9; - - public static final int ERROR_SOCKET_CREATION = -10; - - public static final int ERROR_SOCKET_NOT_CONNECTED = -11; - - public static final int ERROR_BUFFER_TO_SMALL = -12; - - public static final int ERROR_SAP_USED = -13; - - public static final int ERROR_SERVICE_NAME_USED = -14; - - public static final int ERROR_SOCKET_OPTIONS = -15; - - public static final int ERROR_NFC_ON = -16; - - public static final int ERROR_NOT_INITIALIZED = -17; - - public static final int ERROR_SE_ALREADY_SELECTED = -18; - - public static final int ERROR_SE_CONNECTED = -19; - - public static final int ERROR_NO_SE_CONNECTED = -20; - - public static final int ERROR_NOT_SUPPORTED = -21; - -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/IntentConverter.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/IntentConverter.java deleted file mode 100644 index 2df49bb..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/IntentConverter.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.github.skjolber.android.nfc; - -import android.content.Intent; -import android.nfc.NdefMessage; -import android.nfc.NfcAdapter; -import android.os.Bundle; -import android.os.Parcelable; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -public class IntentConverter { - - - public static Intent convert(Intent input) { - - Intent output = new Intent(); - - output.setAction(input.getAction()); - - // detect supported types - if(input.hasExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)) { - - Parcelable[] messages = input.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); - - Bundle extras = new Bundle(); - extras.putParcelableArray(NfcAdapter.EXTRA_NDEF_MESSAGES, messages); - - output.putExtras(extras); - } - - if(input.hasExtra(NfcAdapter.EXTRA_TAG)) { - android.nfc.Tag tag = (android.nfc.Tag) input.getParcelableExtra(NfcAdapter.EXTRA_TAG); - - output.putExtra(NfcAdapter.EXTRA_TAG, new TagWrapper(tag)); - } - - if(input.hasExtra(NfcAdapter.EXTRA_AID)) { - output.putExtra(NfcAdapter.EXTRA_AID, input.getParcelableExtra(NfcAdapter.EXTRA_AID)); - } - - - if(input.hasExtra(NfcAdapter.EXTRA_ID)) { - byte[] id = input.getByteArrayExtra(NfcAdapter.EXTRA_ID); - - output.putExtra(NfcAdapter.EXTRA_ID, id); - } - - // TODO forward all types - - return output; - } - -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/Tag.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/Tag.java deleted file mode 100644 index a99d2cd..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/Tag.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.github.skjolber.android.nfc; - -import android.os.Bundle; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.RemoteException; - -import com.github.skjolber.android.nfc.tech.IsoDep; -import com.github.skjolber.android.nfc.tech.IsoDepImpl; -import com.github.skjolber.android.nfc.tech.IsoDepWrapper; -import com.github.skjolber.android.nfc.tech.TagTechnology; - -import java.io.IOException; - -public abstract class Tag implements Parcelable { - - /** - * Get an instance of {@link Tag} for the given tag. - * - * @return a wrapped tag - */ - public static Tag get(android.nfc.Tag tag) { - return new TagWrapper(tag); - } - - /** - * Construct a mock Tag. - *

This is an application constructed tag, so NfcAdapter methods on this Tag may fail - * with {@link IllegalArgumentException} since it does not represent a physical Tag. - *

This constructor might be useful for mock testing. - * @param id The tag identifier, can be null - * @param techList must not be null - * @return freshly constructed tag - */ - public static Tag createMockTag(byte[] id, int[] techList, Bundle[] techListExtras) { - // set serviceHandle to 0 and tagService to null to indicate mock tag - return new TagImpl(id, techList, techListExtras, 0, null); - } - - public abstract byte[] getId(); - - public abstract String[] getTechList(); - -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/TagImpl.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/TagImpl.java deleted file mode 100644 index 983736b..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/TagImpl.java +++ /dev/null @@ -1,455 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.github.skjolber.android.nfc; - -import android.content.Context; - -import com.github.skjolber.android.nfc.tech.IsoDepImpl; -import com.github.skjolber.android.nfc.tech.MifareClassicImpl; -import com.github.skjolber.android.nfc.tech.MifareUltralightImpl; -import com.github.skjolber.android.nfc.tech.NdefImpl; - -import com.github.skjolber.android.nfc.tech.NdefFormatable; -import com.github.skjolber.android.nfc.tech.NfcA; -import com.github.skjolber.android.nfc.tech.NfcB; -import com.github.skjolber.android.nfc.tech.NfcBarcode; -import com.github.skjolber.android.nfc.tech.NfcF; -import com.github.skjolber.android.nfc.tech.NfcV; - -import com.github.skjolber.android.nfc.tech.TagTechnology; -import android.os.Bundle; -import android.os.Parcel; -import android.os.Parcelable; -import android.os.RemoteException; - -import java.io.IOException; -import java.util.Arrays; -import java.util.HashMap; - -/** - * Represents an NFC tag that has been discovered. - *

- * {@link TagImpl} is an immutable object that represents the state of a NFC tag at - * the time of discovery. It can be used as a handle to {@link TagTechnology} classes - * to perform advanced operations, or directly queried for its ID via {@link #getId} and the - * set of technologies it contains via {@link #getTechList}. Arrays passed to and - * returned by this class are not cloned, so be careful not to modify them. - *

- * A new tag object is created every time a tag is discovered (comes into range), even - * if it is the same physical tag. If a tag is removed and then returned into range, then - * only the most recent tag object can be successfully used to create a {@link TagTechnology}. - * - *

Tag Dispatch

- * When a tag is discovered, a {@link TagImpl} object is created and passed to a - * single activity via the {@link android.nfc.NfcAdapter#EXTRA_TAG} extra in an - * {@link android.content.Intent} via {@link Context#startActivity}. A four stage dispatch is used - * to select the - * most appropriate activity to handle the tag. The Android OS executes each stage in order, - * and completes dispatch as soon as a single matching activity is found. If there are multiple - * matching activities found at any one stage then the Android activity chooser dialog is shown - * to allow the user to select the activity to receive the tag. - * - *

The Tag dispatch mechanism was designed to give a high probability of dispatching - * a tag to the correct activity without showing the user an activity chooser dialog. - * This is important for NFC interactions because they are very transient -- if a user has to - * move the Android device to choose an application then the connection will likely be broken. - * - *

1. Foreground activity dispatch

- * A foreground activity that has called - * {@link android.nfc.NfcAdapter#enableForegroundDispatch NfcAdapter.enableForegroundDispatch()} is - * given priority. See the documentation on - * {@link android.nfc.NfcAdapter#enableForegroundDispatch NfcAdapter.enableForegroundDispatch()} for - * its usage. - *

2. NDEF data dispatch

- * If the tag contains NDEF data the system inspects the first {@link android.nfc.NdefRecord} in the first - * {@link android.nfc.NdefMessage}. If the record is a URI, SmartPoster, or MIME data - * {@link Context#startActivity} is called with {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED}. For URI - * and SmartPoster records the URI is put into the intent's data field. For MIME records the MIME - * type is put in the intent's type field. This allows activities to register to be launched only - * when data they know how to handle is present on a tag. This is the preferred method of handling - * data on a tag since NDEF data can be stored on many types of tags and doesn't depend on a - * specific tag technology. - * See {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} for more detail. If the tag does not contain - * NDEF data, or if no activity is registered - * for {@link android.nfc.NfcAdapter#ACTION_NDEF_DISCOVERED} with a matching data URI or MIME type then dispatch - * moves to stage 3. - *

3. Tag Technology dispatch

- * {@link Context#startActivity} is called with {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} to - * dispatch the tag to an activity that can handle the technologies present on the tag. - * Technologies are defined as sub-classes of {@link TagTechnology}, see the package - * {@link android.nfc.tech}. The Android OS looks for an activity that can handle one or - * more technologies in the tag. See {@link android.nfc.NfcAdapter#ACTION_TECH_DISCOVERED} for more detail. - *

4. Fall-back dispatch

- * If no activity has been matched then {@link Context#startActivity} is called with - * {@link android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED}. This is intended as a fall-back mechanism. - * See {@link android.nfc.NfcAdapter#ACTION_TAG_DISCOVERED}. - * - *

NFC Tag Background

- * An NFC tag is a passive NFC device, powered by the NFC field of this Android device while - * it is in range. Tag's can come in many forms, such as stickers, cards, key fobs, or - * even embedded in a more sophisticated device. - *

- * Tags can have a wide range of capabilities. Simple tags just offer read/write semantics, - * and contain some one time - * programmable areas to make read-only. More complex tags offer math operations - * and per-sector access control and authentication. The most sophisticated tags - * contain operating environments allowing complex interactions with the - * code executing on the tag. Use {@link TagTechnology} classes to access a broad - * range of capabilities available in NFC tags. - *

- */ -public class TagImpl extends Tag { - - final byte[] mId; - final int[] mTechList; - final String[] mTechStringList; - final Bundle[] mTechExtras; - final int mServiceHandle; // for use by NFC service, 0 indicates a mock - final INfcTag mTagService; // interface to NFC service, will be null if mock tag - - int mConnectedTechnology; - - /** - * Hidden constructor to be used by NFC service and internal classes. - */ - public TagImpl(byte[] id, int[] techList, Bundle[] techListExtras, int serviceHandle, - INfcTag tagService) { - if (techList == null) { - throw new IllegalArgumentException("rawTargets cannot be null"); - } - mId = id; - mTechList = Arrays.copyOf(techList, techList.length); - mTechStringList = generateTechStringList(techList); - // Ensure mTechExtras is as long as mTechList - mTechExtras = Arrays.copyOf(techListExtras, techList.length); - mServiceHandle = serviceHandle; - mTagService = tagService; - - mConnectedTechnology = -1; - } - - /** - * - * Translate the wrapped classes to the original names. - * - * @return list of tech types (starting with android.nfc.*). - */ - - private String[] generateTechStringList(int[] techList) { - final int size = techList.length; - String[] strings = new String[size]; - for (int i = 0; i < size; i++) { - switch (techList[i]) { - case TagTechnology.ISO_DEP: - strings[i] = android.nfc.tech.IsoDep.class.getName(); - break; - case TagTechnology.MIFARE_CLASSIC: - strings[i] = android.nfc.tech.MifareClassic.class.getName(); - break; - case TagTechnology.MIFARE_ULTRALIGHT: - strings[i] = android.nfc.tech.MifareUltralight.class.getName(); - break; - case TagTechnology.NDEF: - strings[i] = android.nfc.tech.Ndef.class.getName(); - break; - case TagTechnology.NDEF_FORMATABLE: - strings[i] = android.nfc.tech.NdefFormatable.class.getName(); - break; - case TagTechnology.NFC_A: - strings[i] = android.nfc.tech.NfcA.class.getName(); - break; - case TagTechnology.NFC_B: - strings[i] = android.nfc.tech.NfcB.class.getName(); - break; - case TagTechnology.NFC_F: - strings[i] = android.nfc.tech.NfcF.class.getName(); - break; - case TagTechnology.NFC_V: - strings[i] = android.nfc.tech.NfcV.class.getName(); - break; - case TagTechnology.NFC_BARCODE: - strings[i] = android.nfc.tech.NfcBarcode.class.getName(); - break; - default: - throw new IllegalArgumentException("Unknown tech type " + techList[i]); - } - } - return strings; - } - - static int[] getTechCodesFromStrings(String[] techStringList) throws IllegalArgumentException { - if (techStringList == null) { - throw new IllegalArgumentException("List cannot be null"); - } - int[] techIntList = new int[techStringList.length]; - HashMap stringToCodeMap = getTechStringToCodeMap(); - for (int i = 0; i < techStringList.length; i++) { - Integer code = stringToCodeMap.get(techStringList[i]); - - if (code == null) { - throw new IllegalArgumentException("Unknown tech type " + techStringList[i]); - } - - techIntList[i] = code.intValue(); - } - return techIntList; - } - - private static HashMap getTechStringToCodeMap() { - HashMap techStringToCodeMap = new HashMap(); - - techStringToCodeMap.put(IsoDepImpl.class.getName(), TagTechnology.ISO_DEP); - techStringToCodeMap.put(MifareClassicImpl.class.getName(), TagTechnology.MIFARE_CLASSIC); - techStringToCodeMap.put(MifareUltralightImpl.class.getName(), TagTechnology.MIFARE_ULTRALIGHT); - techStringToCodeMap.put(NdefImpl.class.getName(), TagTechnology.NDEF); - techStringToCodeMap.put(NdefFormatable.class.getName(), TagTechnology.NDEF_FORMATABLE); - techStringToCodeMap.put(NfcA.class.getName(), TagTechnology.NFC_A); - techStringToCodeMap.put(NfcB.class.getName(), TagTechnology.NFC_B); - techStringToCodeMap.put(NfcF.class.getName(), TagTechnology.NFC_F); - techStringToCodeMap.put(NfcV.class.getName(), TagTechnology.NFC_V); - techStringToCodeMap.put(NfcBarcode.class.getName(), TagTechnology.NFC_BARCODE); - return techStringToCodeMap; - } - - /** - * For use by NfcService only. - * @hide - */ - public int getServiceHandle() { - return mServiceHandle; - } - - /** - * For use by NfcService only. - * @hide - */ - public int[] getTechCodeList() { - return mTechList; - } - - /** - * Get the Tag Identifier (if it has one). - *

The tag identifier is a low level serial number, used for anti-collision - * and identification. - *

Most tags have a stable unique identifier - * (UID), but some tags will generate a random ID every time they are discovered - * (RID), and there are some tags with no ID at all (the byte array will be zero-sized). - *

The size and format of an ID is specific to the RF technology used by the tag. - *

This function retrieves the ID as determined at discovery time, and does not - * perform any further RF communication or block. - * @return ID as byte array, never null - */ - @Override - public byte[] getId() { - return mId; - } - - /** - * Get the technologies available in this tag, as fully qualified class names. - *

- * A technology is an implementation of the {@link TagTechnology} interface, - * and can be instantiated by calling the static get(Tag) - * method on the implementation with this Tag. The {@link TagTechnology} - * object can then be used to perform advanced, technology-specific operations on a tag. - *

- * Android defines a mandatory set of technologies that must be correctly - * enumerated by all Android NFC devices, and an optional - * set of proprietary technologies. - * See {@link TagTechnology} for more details. - *

- * The ordering of the returned array is undefined and should not be relied upon. - * @return an array of fully-qualified {@link TagTechnology} class-names. - */ - @Override - public String[] getTechList() { - return mTechStringList; - } - - /** - * Rediscover the technologies available on this tag. - *

- * The technologies that are available on a tag may change due to - * operations being performed on a tag. For example, formatting a - * tag as NDEF adds the {@link NdefImpl} technology. The rediscover - * method reenumerates the available technologies on the tag - * and returns a new {@link TagImpl} object containing these technologies. - *

- * You may not be connected to any of this {@link TagImpl}'s technologies - * when calling this method. - * This method guarantees that you will be returned the same Tag - * if it is still in the field. - *

May cause RF activity and may block. Must not be called - * from the main application thread. A blocked call will be canceled with - * {@link IOException} by calling #close from another thread. - *

Does not remove power from the RF field, so a tag having a random - * ID should not change its ID. - * @return the rediscovered tag object. - * @throws IOException if the tag cannot be rediscovered - * @hide - */ - // TODO See if we need TagLostException - // TODO Unhide for ICS - // TODO Update documentation to make sure it matches with the final - // implementation. - public Tag rediscover() throws IOException { - if (getConnectedTechnology() != -1) { - throw new IllegalStateException("Close connection to the technology first!"); - } - - if (mTagService == null) { - throw new IOException("Mock tags don't support this operation."); - } - try { - TagImpl newTag = (TagImpl)mTagService.rediscover(getServiceHandle()); - if (newTag != null) { - return newTag; - } else { - throw new IOException("Failed to rediscover tag"); - } - } catch (RemoteException e) { - throw new IOException("NFC service dead"); - } - } - - - public boolean hasTech(int techType) { - for (int tech : mTechList) { - if (tech == techType) return true; - } - return false; - } - - public Bundle getTechExtras(int tech) { - int pos = -1; - for (int idx = 0; idx < mTechList.length; idx++) { - if (mTechList[idx] == tech) { - pos = idx; - break; - } - } - if (pos < 0) { - return null; - } - - return mTechExtras[pos]; - } - - public INfcTag getTagService() { - return mTagService; - } - - /** - * Human-readable description of the tag, for debugging. - */ - @Override - public String toString() { - StringBuilder sb = new StringBuilder("TAG: Tech ["); - String[] techList = getTechList(); - int length = techList.length; - for (int i = 0; i < length; i++) { - sb.append(techList[i]); - if (i < length - 1) { - sb.append(", "); - } - } - sb.append("]"); - return sb.toString(); - } - - /*package*/ static byte[] readBytesWithNull(Parcel in) { - int len = in.readInt(); - byte[] result = null; - if (len >= 0) { - result = new byte[len]; - in.readByteArray(result); - } - return result; - } - - /*package*/ static void writeBytesWithNull(Parcel out, byte[] b) { - if (b == null) { - out.writeInt(-1); - return; - } - out.writeInt(b.length); - out.writeByteArray(b); - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - // Null mTagService means this is a mock tag - int isMock = (mTagService == null)?1:0; - - writeBytesWithNull(dest, mId); - dest.writeInt(mTechList.length); - dest.writeIntArray(mTechList); - dest.writeTypedArray(mTechExtras, 0); - dest.writeInt(mServiceHandle); - dest.writeInt(isMock); - if (isMock == 0) { - dest.writeStrongBinder(mTagService.asBinder()); - } - } - - public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - @Override - public TagImpl createFromParcel(Parcel in) { - INfcTag tagService; - - // Tag fields - byte[] id = TagImpl.readBytesWithNull(in); - int[] techList = new int[in.readInt()]; - in.readIntArray(techList); - Bundle[] techExtras = in.createTypedArray(Bundle.CREATOR); - int serviceHandle = in.readInt(); - int isMock = in.readInt(); - if (isMock == 0) { - tagService = INfcTag.Stub.asInterface(in.readStrongBinder()); - } - else { - tagService = null; - } - - return new TagImpl(id, techList, techExtras, serviceHandle, tagService); - } - - @Override - public TagImpl[] newArray(int size) { - return new TagImpl[size]; - } - }; - - public synchronized boolean setConnectedTechnology(int technology) { - if (mConnectedTechnology != -1) { - return false; - } - mConnectedTechnology = technology; - return true; - } - - public int getConnectedTechnology() { - return mConnectedTechnology; - } - - public void setTechnologyDisconnected() { - mConnectedTechnology = -1; - } -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/TagWrapper.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/TagWrapper.java deleted file mode 100644 index 8d6bf4f..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/TagWrapper.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.github.skjolber.android.nfc; - -import android.os.Bundle; -import android.os.Parcel; - -import java.io.IOException; - -public class TagWrapper extends Tag { - - protected android.nfc.Tag delegate; - - public TagWrapper(android.nfc.Tag delegate) { - this.delegate = delegate; - } - - public byte[] getId() { - return delegate.getId(); - } - - public String[] getTechList() { - return delegate.getTechList(); - } - - public android.nfc.Tag getDelegate() { - return delegate; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeParcelable(this.delegate, flags); - } - - protected TagWrapper(Parcel in) { - this.delegate = in.readParcelable(android.nfc.Tag.class.getClassLoader()); - } - - public static final Creator CREATOR = new Creator() { - @Override - public TagWrapper createFromParcel(Parcel source) { - return new TagWrapper(source); - } - - @Override - public TagWrapper[] newArray(int size) { - return new TagWrapper[size]; - } - }; -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/TechListParcel.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/TechListParcel.java deleted file mode 100644 index 94fd349..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/TechListParcel.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package com.github.skjolber.android.nfc; - - -import android.os.Parcel; -import android.os.Parcelable; - -public class TechListParcel implements Parcelable { - - private String[][] mTechLists; - - public TechListParcel(String[]... strings) { - mTechLists = strings; - } - - public String[][] getTechLists() { - return mTechLists; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - int count = mTechLists.length; - dest.writeInt(count); - for (int i = 0; i < count; i++) { - String[] techList = mTechLists[i]; - dest.writeStringArray(techList); - } - } - - public static final Creator CREATOR = new Creator() { - @Override - public TechListParcel createFromParcel(Parcel source) { - int count = source.readInt(); - String[][] techLists = new String[count][]; - for (int i = 0; i < count; i++) { - techLists[i] = source.createStringArray(); - } - return new TechListParcel(techLists); - } - - @Override - public TechListParcel[] newArray(int size) { - return new TechListParcel[size]; - } - }; -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/TransceiveResult.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/TransceiveResult.java deleted file mode 100644 index 9072e42..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/TransceiveResult.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2011, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.github.skjolber.android.nfc; - -import android.nfc.TagLostException; -import android.os.Parcel; -import android.os.Parcelable; - -import java.io.IOException; - -/** - * Class used to pipe transceive result from the NFC service. - * - */ -public final class TransceiveResult implements Parcelable{ - - public static final int RESULT_SUCCESS = 0; - public static final int RESULT_FAILURE = 1; - public static final int RESULT_TAGLOST = 2; - public static final int RESULT_EXCEEDED_LENGTH = 3; - - final int mResult; - final byte[] mResponseData; - - public TransceiveResult(final int result, final byte[] data) { - mResult = result; - mResponseData = data; - } - - public byte[] getResponseOrThrow() throws IOException { - switch (mResult) { - case RESULT_SUCCESS: - return mResponseData; - case RESULT_TAGLOST: - throw new TagLostException("Tag was lost."); - case RESULT_EXCEEDED_LENGTH: - throw new IOException("Transceive length exceeds supported maximum"); - default: - throw new IOException("Transceive failed"); - } - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(mResult); - if (mResult == RESULT_SUCCESS) { - dest.writeInt(mResponseData.length); - dest.writeByteArray(mResponseData); - } - } - - public static final Parcelable.Creator CREATOR = - new Parcelable.Creator() { - @Override - public TransceiveResult createFromParcel(Parcel in) { - int result = in.readInt(); - byte[] responseData; - - if (result == RESULT_SUCCESS) { - int responseLength = in.readInt(); - responseData = new byte[responseLength]; - in.readByteArray(responseData); - } else { - responseData = null; - } - return new TransceiveResult(result, responseData); - } - - @Override - public TransceiveResult[] newArray(int size) { - return new TransceiveResult[size]; - } - }; - -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/BasicTagTechnology.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/BasicTagTechnology.java deleted file mode 100644 index d35c052..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/BasicTagTechnology.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.github.skjolber.android.nfc.tech; - -import android.os.RemoteException; -import android.util.Log; - -import com.github.skjolber.android.nfc.Tag; - -import java.io.IOException; - -interface BasicTagTechnology extends TagTechnology { - -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/BasicTagTechnologyImpl.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/BasicTagTechnologyImpl.java deleted file mode 100644 index 4851588..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/BasicTagTechnologyImpl.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.github.skjolber.android.nfc.tech; - -import com.github.skjolber.android.nfc.ErrorCodes; -import com.github.skjolber.android.nfc.TagImpl; -import com.github.skjolber.android.nfc.TransceiveResult; - -import android.os.RemoteException; -import android.util.Log; - -import java.io.IOException; - -/** - * A base class for tag technologies that are built on top of transceive(). - */ -public class BasicTagTechnologyImpl implements BasicTagTechnology { - private static final String TAG = "NFC"; - - final TagImpl mTag; - - boolean mIsConnected; - int mSelectedTechnology; - - BasicTagTechnologyImpl(TagImpl tag, int tech) throws RemoteException { - mTag = tag; - mSelectedTechnology = tech; - } - - @Override - public TagImpl getTag() { - return mTag; - } - - /** Internal helper to throw IllegalStateException if the technology isn't connected */ - void checkConnected() { - if ((mTag.getConnectedTechnology() != mSelectedTechnology) || - (mTag.getConnectedTechnology() == -1)) { - throw new IllegalStateException("Call connect() first!"); - } - } - - @Override - public boolean isConnected() { - if (!mIsConnected) { - return false; - } - - try { - return mTag.getTagService().isPresent(mTag.getServiceHandle()); - } catch (RemoteException e) { - Log.e(TAG, "NFC service dead", e); - return false; - } - } - - @Override - public void connect() throws IOException { - try { - int errorCode = mTag.getTagService().connect(mTag.getServiceHandle(), - mSelectedTechnology); - - if (errorCode == ErrorCodes.SUCCESS) { - // Store this in the tag object - if (!mTag.setConnectedTechnology(mSelectedTechnology)) { - Log.e(TAG, "Close other technology first!"); - throw new IOException("Only one TagTechnology can be connected at a time."); - } - mIsConnected = true; - } else if (errorCode == ErrorCodes.ERROR_NOT_SUPPORTED) { - throw new UnsupportedOperationException("Connecting to " + - "this technology is not supported by the NFC " + - "adapter."); - } else { - throw new IOException(); - } - } catch (RemoteException e) { - Log.e(TAG, "NFC service dead", e); - throw new IOException("NFC service died"); - } - } - - public void reconnect() throws IOException { - if (!mIsConnected) { - throw new IllegalStateException("Technology not connected yet"); - } - - try { - int errorCode = mTag.getTagService().reconnect(mTag.getServiceHandle()); - - if (errorCode != ErrorCodes.SUCCESS) { - mIsConnected = false; - mTag.setTechnologyDisconnected(); - throw new IOException(); - } - } catch (RemoteException e) { - mIsConnected = false; - mTag.setTechnologyDisconnected(); - Log.e(TAG, "NFC service dead", e); - throw new IOException("NFC service died"); - } - } - - @Override - public void close() throws IOException { - try { - /* Note that we don't want to physically disconnect the tag, - * but just reconnect to it to reset its state - */ - mTag.getTagService().resetTimeouts(); - mTag.getTagService().reconnect(mTag.getServiceHandle()); - } catch (RemoteException e) { - Log.e(TAG, "NFC service dead", e); - } finally { - mIsConnected = false; - mTag.setTechnologyDisconnected(); - } - } - - public int getMaxTransceiveLengthInternal() { - try { - return mTag.getTagService().getMaxTransceiveLength(mSelectedTechnology); - } catch (RemoteException e) { - Log.e(TAG, "NFC service dead", e); - return 0; - } - } - - public byte[] transceive(byte[] data, boolean raw) throws IOException { - checkConnected(); - - try { - TransceiveResult result = mTag.getTagService().transceive(mTag.getServiceHandle(), - data, raw); - if (result == null) { - throw new IOException("transceive failed"); - } else { - return result.getResponseOrThrow(); - } - } catch (RemoteException e) { - Log.e(TAG, "NFC service dead", e); - throw new IOException("NFC service died"); - } - } -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/IsoDep.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/IsoDep.java deleted file mode 100644 index 48560a1..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/IsoDep.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.github.skjolber.android.nfc.tech; - -import android.os.RemoteException; - -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagImpl; -import com.github.skjolber.android.nfc.TagWrapper; - -import java.io.IOException; - -public abstract class IsoDep implements BasicTagTechnology { - - /** - * Get an instance of {@link IsoDepImpl} for the given tag. - *

Does not cause any RF activity and does not block. - *

Returns null if {@link IsoDepImpl} was not enumerated in {@link TagImpl#getTechList}. - * This indicates the tag does not support ISO-DEP. - * - * @param tag an ISO-DEP compatible tag - * @return ISO-DEP object - */ - public static IsoDep get(Tag tag) { - if(tag instanceof TagImpl) { - TagImpl tagImpl = (TagImpl)tag; - if (!tagImpl.hasTech(TagTechnology.ISO_DEP)) return null; - try { - return new IsoDepImpl(tagImpl); - } catch (RemoteException e) { - return null; - } - } else if(tag instanceof TagWrapper) { - TagWrapper delegate = (TagWrapper)tag; - return new IsoDepWrapper(android.nfc.tech.IsoDep.get(delegate.getDelegate())); - } else { - throw new IllegalArgumentException(); - } - } - - public abstract void setTimeout(int timeout); - - public abstract int getTimeout(); - - public abstract byte[] getHistoricalBytes(); - - public abstract byte[] getHiLayerResponse(); - - public abstract byte[] transceive(byte[] data) throws IOException; - - public abstract int getMaxTransceiveLength(); - - public abstract boolean isExtendedLengthApduSupported(); -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/IsoDepImpl.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/IsoDepImpl.java deleted file mode 100644 index 5ac8541..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/IsoDepImpl.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.github.skjolber.android.nfc.tech; - -import com.github.skjolber.android.nfc.ErrorCodes; -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagWrapper; -import com.github.skjolber.android.nfc.TagImpl; - -import android.os.Bundle; -import android.os.RemoteException; -import android.util.Log; - -import java.io.IOException; - -/** - * Provides access to ISO-DEP (ISO 14443-4) properties and I/O operations on a {@link TagImpl}. - * - *

Acquire an {@link IsoDepImpl} object using {@link #get}. - *

The primary ISO-DEP I/O operation is {@link #transceive}. Applications must - * implement their own protocol stack on top of {@link #transceive}. - *

Tags that enumerate the {@link IsoDepImpl} technology in {@link TagImpl#getTechList} - * will also enumerate - * {@link NfcAImpl} or {@link NfcB} (since IsoDep builds on top of either of these). - * - *

Note: Methods that perform I/O operations - * require the {@link android.Manifest.permission#NFC} permission. - */ -public class IsoDepImpl extends IsoDep { - private static final String TAG = "NFC"; - - public static final String EXTRA_HI_LAYER_RESP = "hiresp"; - public static final String EXTRA_HIST_BYTES = "histbytes"; - - private byte[] mHiLayerResponse = null; - private byte[] mHistBytes = null; - - private BasicTagTechnologyImpl delegate; - - public IsoDepImpl(TagImpl tag) - throws RemoteException { - this.delegate = new BasicTagTechnologyImpl(tag, TagTechnology.ISO_DEP); - Bundle extras = tag.getTechExtras(TagTechnology.ISO_DEP); - if (extras != null) { - mHiLayerResponse = extras.getByteArray(EXTRA_HI_LAYER_RESP); - mHistBytes = extras.getByteArray(EXTRA_HIST_BYTES); - } - } - - /** - * Set the timeout of {@link #transceive} in milliseconds. - *

The timeout only applies to ISO-DEP {@link #transceive}, and is - * reset to a default value when {@link #close} is called. - *

Setting a longer timeout may be useful when performing - * transactions that require a long processing time on the tag - * such as key generation. - * - *

Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param timeout timeout value in milliseconds - */ - @Override - public void setTimeout(int timeout) { - try { - int err = delegate.getTag().getTagService().setTimeout(TagTechnology.ISO_DEP, timeout); - if (err != ErrorCodes.SUCCESS) { - throw new IllegalArgumentException("The supplied timeout is not valid"); - } - } catch (RemoteException e) { - Log.e(TAG, "NFC service dead", e); - } - } - - /** - * Get the current timeout for {@link #transceive} in milliseconds. - * - *

Requires the {@link android.Manifest.permission#NFC} permission. - * - * @return timeout value in milliseconds - */ - @Override - public int getTimeout() { - try { - return delegate.getTag().getTagService().getTimeout(TagTechnology.ISO_DEP); - } catch (RemoteException e) { - Log.e(TAG, "NFC service dead", e); - return 0; - } - } - - /** - * Return the ISO-DEP historical bytes for {@link NfcAImpl} tags. - *

Does not cause any RF activity and does not block. - *

The historical bytes can be used to help identify a tag. They are present - * only on {@link IsoDepImpl} tags that are based on {@link NfcAImpl} RF technology. - * If this tag is not {@link NfcAImpl} then null is returned. - *

In ISO 14443-4 terminology, the historical bytes are a subset of the RATS - * response. - * - * @return ISO-DEP historical bytes, or null if this is not a {@link NfcAImpl} tag - */ - @Override - public byte[] getHistoricalBytes() { - return mHistBytes; - } - - /** - * Return the higher layer response bytes for {@link NfcB} tags. - *

Does not cause any RF activity and does not block. - *

The higher layer response bytes can be used to help identify a tag. - * They are present only on {@link IsoDepImpl} tags that are based on {@link NfcB} - * RF technology. If this tag is not {@link NfcB} then null is returned. - *

In ISO 14443-4 terminology, the higher layer bytes are a subset of the - * ATTRIB response. - * - * @return ISO-DEP historical bytes, or null if this is not a {@link NfcB} tag - */ - @Override - public byte[] getHiLayerResponse() { - return mHiLayerResponse; - } - - /** - * Send raw ISO-DEP data to the tag and receive the response. - * - *

Applications must only send the INF payload, and not the start of frame and - * end of frame indicators. Applications do not need to fragment the payload, it - * will be automatically fragmented and defragmented by {@link #transceive} if - * it exceeds FSD/FSC limits. - * - *

Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes - * that can be sent with {@link #transceive}. - * - *

This is an I/O operation and will block until complete. It must - * not be called from the main application thread. A blocked call will be canceled with - * {@link IOException} if {@link #close} is called from another thread. - * - *

Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param data command bytes to send, must not be null - * @return response bytes received, will not be null - * @throws android.nfc.TagLostException if the tag leaves the field - * @throws IOException if there is an I/O failure, or this operation is canceled - */ - @Override - public byte[] transceive(byte[] data) throws IOException { - return delegate.transceive(data, true); - } - - /** - * Return the maximum number of bytes that can be sent with {@link #transceive}. - * @return the maximum number of bytes that can be sent with {@link #transceive}. - */ - @Override - public int getMaxTransceiveLength() { - return delegate.getMaxTransceiveLengthInternal(); - } - - /** - *

Standard APDUs have a 1-byte length field, allowing a maximum of - * 255 payload bytes, which results in a maximum APDU length of 261 bytes. - * - *

Extended length APDUs have a 3-byte length field, allowing 65535 - * payload bytes. - * - *

Some NFC adapters, like the one used in the Nexus S and the Galaxy Nexus - * do not support extended length APDUs. They are expected to be well-supported - * in the future though. Use this method to check for extended length APDU - * support. - * - * @return whether the NFC adapter on this device supports extended length APDUs. - */ - @Override - public boolean isExtendedLengthApduSupported() { - try { - return delegate.getTag().getTagService().getExtendedLengthApdusSupported(); - } catch (RemoteException e) { - Log.e(TAG, "NFC service dead", e); - return false; - } - } - - @Override - public Tag getTag() { - return delegate.getTag(); - } - - @Override - public void connect() throws IOException { - delegate.connect(); - } - - @Override - public void close() throws IOException { - delegate.close(); - } - - @Override - public boolean isConnected() { - return delegate.isConnected(); - } - -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/IsoDepWrapper.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/IsoDepWrapper.java deleted file mode 100644 index 5b88ab5..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/IsoDepWrapper.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.github.skjolber.android.nfc.tech; - -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagWrapper; - -import java.io.IOException; - -public class IsoDepWrapper extends IsoDep { - - protected android.nfc.tech.IsoDep delegate; - - public IsoDepWrapper(android.nfc.tech.IsoDep delegate) { - this.delegate = delegate; - } - - @Override - public void setTimeout(int timeout) { - delegate.setTimeout(timeout); - } - - @Override - public int getTimeout() { - return delegate.getTimeout(); - } - - public byte[] getHistoricalBytes() { - return delegate.getHistoricalBytes(); - } - - public byte[] getHiLayerResponse() { - return delegate.getHiLayerResponse(); - } - - public byte[] transceive(byte[] data) throws IOException { - return delegate.transceive(data); - } - - public int getMaxTransceiveLength() { - return delegate.getMaxTransceiveLength(); - } - - public boolean isExtendedLengthApduSupported() { - return this.delegate.isExtendedLengthApduSupported(); - } - - @Override - public Tag getTag() { - return new TagWrapper(delegate.getTag()); - } - - @Override - public void connect() throws IOException { - delegate.connect(); - } - - @Override - public void close() throws IOException { - delegate.close(); - } - - @Override - public boolean isConnected() { - return delegate.isConnected(); - } - -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/MifareClassic.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/MifareClassic.java deleted file mode 100644 index 626e114..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/MifareClassic.java +++ /dev/null @@ -1,117 +0,0 @@ -package com.github.skjolber.android.nfc.tech; - -import android.os.RemoteException; - -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagWrapper; -import com.github.skjolber.android.nfc.TagImpl; - -import java.io.IOException; - -public abstract class MifareClassic implements BasicTagTechnology { - /** - * The default factory key. - */ - public static byte[] KEY_DEFAULT = - {(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF}; - /** - * The well-known key for tags formatted according to the - * MIFARE Application Directory (MAD) specification. - */ - byte[] KEY_MIFARE_APPLICATION_DIRECTORY = - {(byte)0xA0,(byte)0xA1,(byte)0xA2,(byte)0xA3,(byte)0xA4,(byte)0xA5}; - /** - * The well-known key for tags formatted according to the - * NDEF on MIFARE Classic specification. - */ - byte[] KEY_NFC_FORUM = - {(byte)0xD3,(byte)0xF7,(byte)0xD3,(byte)0xF7,(byte)0xD3,(byte)0xF7}; - /** A MIFARE Classic compatible card of unknown type */ - public final int TYPE_UNKNOWN = -1; - /** A MIFARE Classic tag */ - public final int TYPE_CLASSIC = 0; - /** A MIFARE Plus tag */ - public final int TYPE_PLUS = 1; - /** A MIFARE Pro tag */ - public final int TYPE_PRO = 2; - /** Tag contains 16 sectors, each with 4 blocks. */ - public final int SIZE_1K = 1024; - /** Tag contains 32 sectors, each with 4 blocks. */ - public final int SIZE_2K = 2048; - /** - * Tag contains 40 sectors. The first 32 sectors contain 4 blocks and the last 8 sectors - * contain 16 blocks. - */ - public final int SIZE_4K = 4096; - /** Tag contains 5 sectors, each with 4 blocks. */ - public final int SIZE_MINI = 320; - /** Size of a MIFARE Classic block (in bytes) */ - public final int BLOCK_SIZE = 16; - - /** - * Get an instance of {@link MifareClassicImpl} for the given tag. - *

Does not cause any RF activity and does not block. - *

Returns null if {@link MifareClassicImpl} was not enumerated in {@link TagImpl#getTechList}. - * This indicates the tag is not MIFARE Classic compatible, or this Android - * device does not support MIFARE Classic. - * - * @param tag an MIFARE Classic compatible tag - * @return MIFARE Classic object - */ - public static MifareClassic get(Tag tag) { - if(tag instanceof TagImpl) { - TagImpl tagImpl = (TagImpl)tag; - if (!tagImpl.hasTech(TagTechnology.MIFARE_CLASSIC)) return null; - try { - return new MifareClassicImpl(tagImpl); - } catch (RemoteException e) { - return null; - } - } else if(tag instanceof TagWrapper) { - TagWrapper delegate = (TagWrapper)tag; - return new MifareClassicWrapper(android.nfc.tech.MifareClassic.get(delegate.getDelegate())); - } else { - throw new IllegalArgumentException(); - } - } - - - - public abstract int getType(); - - public abstract int getSize(); - - public abstract int getSectorCount(); - - public abstract int getBlockCount(); - - public abstract int getBlockCountInSector(int sectorIndex); - - public abstract int blockToSector(int blockIndex); - - public abstract int sectorToBlock(int sectorIndex); - - public abstract boolean authenticateSectorWithKeyA(int sectorIndex, byte[] key) throws IOException; - - public abstract boolean authenticateSectorWithKeyB(int sectorIndex, byte[] key) throws IOException; - - public abstract byte[] readBlock(int blockIndex) throws IOException; - - public abstract void writeBlock(int blockIndex, byte[] data) throws IOException; - - public abstract void increment(int blockIndex, int value) throws IOException; - - public abstract void decrement(int blockIndex, int value) throws IOException; - - public abstract void transfer(int blockIndex) throws IOException; - - public abstract void restore(int blockIndex) throws IOException; - - public abstract byte[] transceive(byte[] data) throws IOException; - - public abstract int getMaxTransceiveLength(); - - public abstract void setTimeout(int timeout); - - public abstract int getTimeout(); -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/MifareClassicImpl.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/MifareClassicImpl.java deleted file mode 100644 index 6a2b74b..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/MifareClassicImpl.java +++ /dev/null @@ -1,636 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.github.skjolber.android.nfc.tech; - -import com.github.skjolber.android.nfc.ErrorCodes; -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagImpl; - -import android.nfc.TagLostException; -import android.os.RemoteException; -import android.util.Log; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -/** - * Provides access to MIFARE Classic properties and I/O operations on a {@link TagImpl}. - * - *

Acquire a {@link MifareClassicImpl} object using {@link #get}. - * - *

MIFARE Classic is also known as MIFARE Standard. - *

MIFARE Classic tags are divided into sectors, and each sector is sub-divided into - * blocks. Block size is always 16 bytes ({@link #BLOCK_SIZE}. Sector size varies. - *

    - *
  • MIFARE Classic Mini are 320 bytes ({@link #SIZE_MINI}), with 5 sectors each of 4 blocks. - *
  • MIFARE Classic 1k are 1024 bytes ({@link #SIZE_1K}), with 16 sectors each of 4 blocks. - *
  • MIFARE Classic 2k are 2048 bytes ({@link #SIZE_2K}), with 32 sectors each of 4 blocks. - *
  • MIFARE Classic 4k are 4096 bytes ({@link #SIZE_4K}). The first 32 sectors contain 4 blocks - * and the last 8 sectors contain 16 blocks. - *
- * - *

MIFARE Classic tags require authentication on a per-sector basis before any - * other I/O operations on that sector can be performed. There are two keys per sector, - * and ACL bits determine what I/O operations are allowed on that sector after - * authenticating with a key. {@see #authenticateSectorWithKeyA} and - * {@see #authenticateSectorWithKeyB}. - * - *

Three well-known authentication keys are defined in this class: - * {@link #KEY_DEFAULT}, {@link #KEY_MIFARE_APPLICATION_DIRECTORY}, - * {@link #KEY_NFC_FORUM}. - *

    - *
  • {@link #KEY_DEFAULT} is the default factory key for MIFARE Classic. - *
  • {@link #KEY_MIFARE_APPLICATION_DIRECTORY} is the well-known key for - * MIFARE Classic cards that have been formatted according to the - * MIFARE Application Directory (MAD) specification. - *
  • {@link #KEY_NFC_FORUM} is the well-known key for MIFARE Classic cards that - * have been formatted according to the NXP specification for NDEF on MIFARE Classic. - * - *

    Implementation of this class on a Android NFC device is optional. - * If it is not implemented, then - * {@link MifareClassicImpl} will never be enumerated in {@link TagImpl#getTechList}. - * If it is enumerated, then all {@link MifareClassicImpl} I/O operations will be supported, - * and {@link NdefImpl#MIFARE_CLASSIC} NDEF tags will also be supported. In either case, - * {@link NfcAImpl} will also be enumerated on the tag, because all MIFARE Classic tags are also - * {@link NfcAImpl}. - * - *

    Note: Methods that perform I/O operations - * require the {@link android.Manifest.permission#NFC} permission. - */ -public final class MifareClassicImpl extends MifareClassic { - - private static final String TAG = "NFC"; - - private static final int MAX_BLOCK_COUNT = 256; - private static final int MAX_SECTOR_COUNT = 40; - - private boolean mIsEmulated; - private int mType; - private int mSize; - - private BasicTagTechnologyImpl delegate; - - public MifareClassicImpl(TagImpl tag) throws RemoteException { - this.delegate = new BasicTagTechnologyImpl(tag, TagTechnology.MIFARE_CLASSIC); - - NfcA a = NfcAImpl.get(tag); // MIFARE Classic is always based on NFC a - - mIsEmulated = false; - - switch (a.getSak()) { - case 0x01: - case 0x08: - mType = TYPE_CLASSIC; - mSize = SIZE_1K; - break; - case 0x09: - mType = TYPE_CLASSIC; - mSize = SIZE_MINI; - break; - case 0x10: - mType = TYPE_PLUS; - mSize = SIZE_2K; - // SecLevel = SL2 - break; - case 0x11: - mType = TYPE_PLUS; - mSize = SIZE_4K; - // Seclevel = SL2 - break; - case 0x18: - mType = TYPE_CLASSIC; - mSize = SIZE_4K; - break; - case 0x28: - mType = TYPE_CLASSIC; - mSize = SIZE_1K; - mIsEmulated = true; - break; - case 0x38: - mType = TYPE_CLASSIC; - mSize = SIZE_4K; - mIsEmulated = true; - break; - case 0x88: - mType = TYPE_CLASSIC; - mSize = SIZE_1K; - // NXP-tag: false - break; - case 0x98: - case 0xB8: - mType = TYPE_PRO; - mSize = SIZE_4K; - break; - default: - // Stack incorrectly reported a MifareClassic. We cannot handle this - // gracefully - we have no idea of the memory layout. Bail. - throw new RuntimeException( - "Tag incorrectly enumerated as MIFARE Classic, SAK = " + a.getSak()); - } - } - - /** - * Return the type of this MIFARE Classic compatible tag. - *

    One of {@link #TYPE_UNKNOWN}, {@link #TYPE_CLASSIC}, {@link #TYPE_PLUS} or - * {@link #TYPE_PRO}. - *

    Does not cause any RF activity and does not block. - * - * @return type - */ - @Override - public int getType() { - return mType; - } - - /** - * Return the size of the tag in bytes - *

    One of {@link #SIZE_MINI}, {@link #SIZE_1K}, {@link #SIZE_2K}, {@link #SIZE_4K}. - * These constants are equal to their respective size in bytes. - *

    Does not cause any RF activity and does not block. - * @return size in bytes - */ - @Override - public int getSize() { - return mSize; - } - - /** - * Return true if the tag is emulated, determined at discovery time. - * These are actually smart-cards that emulate a MIFARE Classic interface. - * They can be treated identically to a MIFARE Classic tag. - * @hide - */ - public boolean isEmulated() { - return mIsEmulated; - } - - /** - * Return the number of MIFARE Classic sectors. - *

    Does not cause any RF activity and does not block. - * @return number of sectors - */ - @Override - public int getSectorCount() { - switch (mSize) { - case SIZE_1K: - return 16; - case SIZE_2K: - return 32; - case SIZE_4K: - return 40; - case SIZE_MINI: - return 5; - default: - return 0; - } - } - - /** - * Return the total number of MIFARE Classic blocks. - *

    Does not cause any RF activity and does not block. - * @return total number of blocks - */ - @Override - public int getBlockCount() { - return mSize / BLOCK_SIZE; - } - - /** - * Return the number of blocks in the given sector. - *

    Does not cause any RF activity and does not block. - * - * @param sectorIndex index of sector, starting from 0 - * @return number of blocks in the sector - */ - @Override - public int getBlockCountInSector(int sectorIndex) { - validateSector(sectorIndex); - - if (sectorIndex < 32) { - return 4; - } else { - return 16; - } - } - - /** - * Return the sector that contains a given block. - *

    Does not cause any RF activity and does not block. - * - * @param blockIndex index of block to lookup, starting from 0 - * @return sector index that contains the block - */ - @Override - public int blockToSector(int blockIndex) { - validateBlock(blockIndex); - - if (blockIndex < 32 * 4) { - return blockIndex / 4; - } else { - return 32 + (blockIndex - 32 * 4) / 16; - } - } - - /** - * Return the first block of a given sector. - *

    Does not cause any RF activity and does not block. - * - * @param sectorIndex index of sector to lookup, starting from 0 - * @return block index of first block in sector - */ - @Override - public int sectorToBlock(int sectorIndex) { - if (sectorIndex < 32) { - return sectorIndex * 4; - } else { - return 32 * 4 + (sectorIndex - 32) * 16; - } - } - - /** - * Authenticate a sector with key A. - * - *

    Successful authentication of a sector with key A enables other - * I/O operations on that sector. The set of operations granted by key A - * key depends on the ACL bits set in that sector. For more information - * see the MIFARE Classic specification on http://www.nxp.com. - * - *

    A failed authentication attempt causes an implicit reconnection to the - * tag, so authentication to other sectors will be lost. - * - *

    This is an I/O operation and will block until complete. It must - * not be called from the main application thread. A blocked call will be canceled with - * {@link IOException} if {@link #close} is called from another thread. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param sectorIndex index of sector to authenticate, starting from 0 - * @param key 6-byte authentication key - * @return true on success, false on authentication failure - * @throws TagLostException if the tag leaves the field - * @throws IOException if there is an I/O failure, or the operation is canceled - */ - @Override - public boolean authenticateSectorWithKeyA(int sectorIndex, byte[] key) throws IOException { - return authenticate(sectorIndex, key, true); - } - - /** - * Authenticate a sector with key B. - * - *

    Successful authentication of a sector with key B enables other - * I/O operations on that sector. The set of operations granted by key B - * depends on the ACL bits set in that sector. For more information - * see the MIFARE Classic specification on http://www.nxp.com. - * - *

    A failed authentication attempt causes an implicit reconnection to the - * tag, so authentication to other sectors will be lost. - * - *

    This is an I/O operation and will block until complete. It must - * not be called from the main application thread. A blocked call will be canceled with - * {@link IOException} if {@link #close} is called from another thread. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param sectorIndex index of sector to authenticate, starting from 0 - * @param key 6-byte authentication key - * @return true on success, false on authentication failure - * @throws android.nfc.TagLostException if the tag leaves the field - * @throws IOException if there is an I/O failure, or the operation is canceled - */ - @Override - public boolean authenticateSectorWithKeyB(int sectorIndex, byte[] key) throws IOException { - return authenticate(sectorIndex, key, false); - } - - private boolean authenticate(int sector, byte[] key, boolean keyA) throws IOException { - validateSector(sector); - delegate.checkConnected(); - - byte[] cmd = new byte[12]; - - // First byte is the command - if (keyA) { - cmd[0] = 0x60; // phHal_eMifareAuthentA - } else { - cmd[0] = 0x61; // phHal_eMifareAuthentB - } - - // Second byte is block address - // Authenticate command takes a block address. Authenticating a block - // of a sector will authenticate the entire sector. - cmd[1] = (byte) sectorToBlock(sector); - - // Next 4 bytes are last 4 bytes of UID - byte[] uid = getTag().getId(); - System.arraycopy(uid, uid.length - 4, cmd, 2, 4); - - // Next 6 bytes are key - System.arraycopy(key, 0, cmd, 6, 6); - - try { - if (delegate.transceive(cmd, false) != null) { - return true; - } - } catch (TagLostException e) { - throw e; - } catch (IOException e) { - // No need to deal with, will return false anyway - } - return false; - } - - /** - * Read 16-byte block. - * - *

    This is an I/O operation and will block until complete. It must - * not be called from the main application thread. A blocked call will be canceled with - * {@link IOException} if {@link #close} is called from another thread. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param blockIndex index of block to read, starting from 0 - * @return 16 byte block - * @throws TagLostException if the tag leaves the field - * @throws IOException if there is an I/O failure, or the operation is canceled - */ - @Override - public byte[] readBlock(int blockIndex) throws IOException { - validateBlock(blockIndex); - delegate.checkConnected(); - - byte[] cmd = { 0x30, (byte) blockIndex }; - return delegate.transceive(cmd, false); - } - - /** - * Write 16-byte block. - * - *

    This is an I/O operation and will block until complete. It must - * not be called from the main application thread. A blocked call will be canceled with - * {@link IOException} if {@link #close} is called from another thread. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param blockIndex index of block to write, starting from 0 - * @param data 16 bytes of data to write - * @throws TagLostException if the tag leaves the field - * @throws IOException if there is an I/O failure, or the operation is canceled - */ - @Override - public void writeBlock(int blockIndex, byte[] data) throws IOException { - validateBlock(blockIndex); - delegate.checkConnected(); - if (data.length != 16) { - throw new IllegalArgumentException("must write 16-bytes"); - } - - byte[] cmd = new byte[data.length + 2]; - cmd[0] = (byte) 0xA0; // MF write command - cmd[1] = (byte) blockIndex; - System.arraycopy(data, 0, cmd, 2, data.length); - - delegate.transceive(cmd, false); - } - - /** - * Increment a value block, storing the result in the temporary block on the tag. - * - *

    This is an I/O operation and will block until complete. It must - * not be called from the main application thread. A blocked call will be canceled with - * {@link IOException} if {@link #close} is called from another thread. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param blockIndex index of block to increment, starting from 0 - * @param value non-negative to increment by - * @throws TagLostException if the tag leaves the field - * @throws IOException if there is an I/O failure, or the operation is canceled - */ - @Override - public void increment(int blockIndex, int value) throws IOException { - validateBlock(blockIndex); - validateValueOperand(value); - delegate.checkConnected(); - - ByteBuffer cmd = ByteBuffer.allocate(6); - cmd.order(ByteOrder.LITTLE_ENDIAN); - cmd.put( (byte) 0xC1 ); - cmd.put( (byte) blockIndex ); - cmd.putInt(value); - - delegate.transceive(cmd.array(), false); - } - - /** - * Decrement a value block, storing the result in the temporary block on the tag. - * - *

    This is an I/O operation and will block until complete. It must - * not be called from the main application thread. A blocked call will be canceled with - * {@link IOException} if {@link #close} is called from another thread. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param blockIndex index of block to decrement, starting from 0 - * @param value non-negative to decrement by - * @throws TagLostException if the tag leaves the field - * @throws IOException if there is an I/O failure, or the operation is canceled - */ - @Override - public void decrement(int blockIndex, int value) throws IOException { - validateBlock(blockIndex); - validateValueOperand(value); - delegate.checkConnected(); - - ByteBuffer cmd = ByteBuffer.allocate(6); - cmd.order(ByteOrder.LITTLE_ENDIAN); - cmd.put( (byte) 0xC0 ); - cmd.put( (byte) blockIndex ); - cmd.putInt(value); - - delegate.transceive(cmd.array(), false); - } - - /** - * Copy from the temporary block to a value block. - * - *

    This is an I/O operation and will block until complete. It must - * not be called from the main application thread. A blocked call will be canceled with - * {@link IOException} if {@link #close} is called from another thread. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param blockIndex index of block to copy to - * @throws TagLostException if the tag leaves the field - * @throws IOException if there is an I/O failure, or the operation is canceled - */ - @Override - public void transfer(int blockIndex) throws IOException { - validateBlock(blockIndex); - delegate.checkConnected(); - - byte[] cmd = { (byte) 0xB0, (byte) blockIndex }; - - delegate.transceive(cmd, false); - } - - /** - * Copy from a value block to the temporary block. - * - *

    This is an I/O operation and will block until complete. It must - * not be called from the main application thread. A blocked call will be canceled with - * {@link IOException} if {@link #close} is called from another thread. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param blockIndex index of block to copy from - * @throws TagLostException if the tag leaves the field - * @throws IOException if there is an I/O failure, or the operation is canceled - */ - @Override - public void restore(int blockIndex) throws IOException { - validateBlock(blockIndex); - delegate.checkConnected(); - - byte[] cmd = { (byte) 0xC2, (byte) blockIndex }; - - delegate.transceive(cmd, false); - } - - /** - * Send raw NfcA data to a tag and receive the response. - * - *

    This is equivalent to connecting to this tag via {@link NfcAImpl} - * and calling {@link NfcAImpl#transceive}. Note that all MIFARE Classic - * tags are based on {@link NfcAImpl} technology. - * - *

    Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes - * that can be sent with {@link #transceive}. - * - *

    This is an I/O operation and will block until complete. It must - * not be called from the main application thread. A blocked call will be canceled with - * {@link IOException} if {@link #close} is called from another thread. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @see NfcAImpl#transceive - */ - @Override - public byte[] transceive(byte[] data) throws IOException { - return delegate.transceive(data, true); - } - - /** - * Return the maximum number of bytes that can be sent with {@link #transceive}. - * @return the maximum number of bytes that can be sent with {@link #transceive}. - */ - @Override - public int getMaxTransceiveLength() { - return delegate.getMaxTransceiveLengthInternal(); - } - - /** - * Set the {@link #transceive} timeout in milliseconds. - * - *

    The timeout only applies to {@link #transceive} on this object, - * and is reset to a default value when {@link #close} is called. - * - *

    Setting a longer timeout may be useful when performing - * transactions that require a long processing time on the tag - * such as key generation. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param timeout timeout value in milliseconds - */ - @Override - public void setTimeout(int timeout) { - try { - int err = delegate.getTag().getTagService().setTimeout(TagTechnology.MIFARE_CLASSIC, timeout); - if (err != ErrorCodes.SUCCESS) { - throw new IllegalArgumentException("The supplied timeout is not valid"); - } - } catch (RemoteException e) { - Log.e(TAG, "NFC service dead", e); - } - } - - /** - * Get the current {@link #transceive} timeout in milliseconds. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @return timeout value in milliseconds - */ - @Override - public int getTimeout() { - try { - return delegate.getTag().getTagService().getTimeout(TagTechnology.MIFARE_CLASSIC); - } catch (RemoteException e) { - Log.e(TAG, "NFC service dead", e); - return 0; - } - } - - private static void validateSector(int sector) { - // Do not be too strict on upper bounds checking, since some cards - // have more addressable memory than they report. For example, - // MIFARE Plus 2k cards will appear as MIFARE Classic 1k cards when in - // MIFARE Classic compatibility mode. - // Note that issuing a command to an out-of-bounds block is safe - the - // tag should report error causing IOException. This validation is a - // helper to guard against obvious programming mistakes. - if (sector < 0 || sector >= MAX_SECTOR_COUNT) { - throw new IndexOutOfBoundsException("sector out of bounds: " + sector); - } - } - - private static void validateBlock(int block) { - // Just looking for obvious out of bounds... - if (block < 0 || block >= MAX_BLOCK_COUNT) { - throw new IndexOutOfBoundsException("block out of bounds: " + block); - } - } - - private static void validateValueOperand(int value) { - if (value < 0) { - throw new IllegalArgumentException("value operand negative"); - } - } - - @Override - public Tag getTag() { - return delegate.getTag(); - } - - @Override - public void connect() throws IOException { - delegate.connect(); - } - - @Override - public void close() throws IOException { - delegate.close(); - } - - @Override - public boolean isConnected() { - return delegate.isConnected(); - } - -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/MifareClassicWrapper.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/MifareClassicWrapper.java deleted file mode 100644 index af9431f..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/MifareClassicWrapper.java +++ /dev/null @@ -1,130 +0,0 @@ -package com.github.skjolber.android.nfc.tech; - -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagWrapper; - -import java.io.IOException; - -public class MifareClassicWrapper extends MifareClassic { - - protected android.nfc.tech.MifareClassic delegate; - - public MifareClassicWrapper(android.nfc.tech.MifareClassic delegate) { - this.delegate = delegate; - } - - @Override - public void setTimeout(int timeout) { - delegate.setTimeout(timeout); - } - - @Override - public int getTimeout() { - return delegate.getTimeout(); - } - - - @Override - public int getType() { - return delegate.getType(); - } - - @Override - public int getSize() { - return delegate.getSize(); - } - - @Override - public int getSectorCount() { - return delegate.getSectorCount(); - } - - @Override - public int getBlockCount() { - return delegate.getBlockCount(); - } - - @Override - public int getBlockCountInSector(int sectorIndex) { - return delegate.getBlockCountInSector(sectorIndex); - } - - @Override - public int blockToSector(int blockIndex) { - return delegate.blockToSector(blockIndex); - } - - @Override - public int sectorToBlock(int sectorIndex) { - return delegate.sectorToBlock(sectorIndex); - } - - @Override - public boolean authenticateSectorWithKeyA(int sectorIndex, byte[] key) throws IOException { - return delegate.authenticateSectorWithKeyA(sectorIndex, key); - } - - @Override - public boolean authenticateSectorWithKeyB(int sectorIndex, byte[] key) throws IOException { - return delegate.authenticateSectorWithKeyB(sectorIndex, key); - } - - @Override - public byte[] readBlock(int blockIndex) throws IOException { - return delegate.readBlock(blockIndex); - } - - @Override - public void writeBlock(int blockIndex, byte[] data) throws IOException { - delegate.writeBlock(blockIndex, data); - } - - @Override - public void increment(int blockIndex, int value) throws IOException { - delegate.increment(blockIndex, value); - } - - @Override - public void decrement(int blockIndex, int value) throws IOException { - delegate.decrement(blockIndex, value); - } - - @Override - public void transfer(int blockIndex) throws IOException { - delegate.transfer(blockIndex); - } - - @Override - public void restore(int blockIndex) throws IOException { - delegate.restore(blockIndex); - } - - public byte[] transceive(byte[] data) throws IOException { - return delegate.transceive(data); - } - - public int getMaxTransceiveLength() { - return delegate.getMaxTransceiveLength(); - } - - @Override - public Tag getTag() { - return new TagWrapper(delegate.getTag()); - } - - @Override - public void connect() throws IOException { - delegate.connect(); - } - - @Override - public void close() throws IOException { - delegate.close(); - } - - @Override - public boolean isConnected() { - return delegate.isConnected(); - } - -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/MifareUltralight.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/MifareUltralight.java deleted file mode 100644 index 148fb9e..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/MifareUltralight.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.github.skjolber.android.nfc.tech; - -import android.os.RemoteException; - -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagWrapper; -import com.github.skjolber.android.nfc.TagImpl; - -import java.io.IOException; - -public abstract class MifareUltralight implements BasicTagTechnology { - /** A MIFARE Ultralight compatible tag of unknown type */ - public static final int TYPE_UNKNOWN = -1; - /** A MIFARE Ultralight tag */ - public static final int TYPE_ULTRALIGHT = 1; - /** A MIFARE Ultralight C tag */ - public static final int TYPE_ULTRALIGHT_C = 2; - /** Size of a MIFARE Ultralight page in bytes */ - public static final int PAGE_SIZE = 4; - - /** - * Get an instance of {@link MifareUltralightImpl} for the given tag. - *

    Returns null if {@link MifareUltralightImpl} was not enumerated in - * {@link TagImpl#getTechList} - this indicates the tag is not MIFARE - * Ultralight compatible, or that this Android - * device does not implement MIFARE Ultralight. - *

    Does not cause any RF activity and does not block. - * - * @param tag an MIFARE Ultralight compatible tag - * @return MIFARE Ultralight object - */ - public static MifareUltralight get(Tag tag) { - if(tag instanceof TagImpl) { - TagImpl tagImpl = (TagImpl)tag; - if (!tagImpl.hasTech(TagTechnology.MIFARE_ULTRALIGHT)) return null; - try { - return new MifareUltralightImpl(tagImpl); - } catch (RemoteException e) { - return null; - } - } else if(tag instanceof TagWrapper) { - TagWrapper delegate = (TagWrapper)tag; - return new MifareUltralightWrapper(android.nfc.tech.MifareUltralight.get(delegate.getDelegate())); - } else { - throw new IllegalArgumentException(); - } - } - - public abstract int getType(); - - public abstract byte[] readPages(int pageOffset) throws IOException; - - public abstract void writePage(int pageOffset, byte[] data) throws IOException; - - public abstract byte[] transceive(byte[] data) throws IOException; - - public abstract int getMaxTransceiveLength(); - - public abstract void setTimeout(int timeout); - - public abstract int getTimeout(); -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/MifareUltralightImpl.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/MifareUltralightImpl.java deleted file mode 100644 index aedbf94..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/MifareUltralightImpl.java +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.github.skjolber.android.nfc.tech; - -import com.github.skjolber.android.nfc.ErrorCodes; -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagImpl; - -import android.os.Bundle; -import android.os.RemoteException; -import android.util.Log; - -import java.io.IOException; - -//TOOD: Ultralight C 3-DES authentication, one-way counter - -/** - * Provides access to MIFARE Ultralight properties and I/O operations on a {@link TagImpl}. - * - *

    Acquire a {@link MifareUltralightImpl} object using {@link #get}. - * - *

    MIFARE Ultralight compatible tags have 4 byte pages {@link #PAGE_SIZE}. - * The primary operations on an Ultralight tag are {@link #readPages} and - * {@link #writePage}. - * - *

    The original MIFARE Ultralight consists of a 64 byte EEPROM. The first - * 4 pages are for the OTP area, manufacturer data, and locking bits. They are - * readable and some bits are writable. The final 12 pages are the user - * read/write area. For more information see the NXP data sheet MF0ICU1. - * - *

    The MIFARE Ultralight C consists of a 192 byte EEPROM. The first 4 pages - * are for OTP, manufacturer data, and locking bits. The next 36 pages are the - * user read/write area. The next 4 pages are additional locking bits, counters - * and authentication configuration and are readable. The final 4 pages are for - * the authentication key and are not readable. For more information see the - * NXP data sheet MF0ICU2. - * - *

    Implementation of this class on a Android NFC device is optional. - * If it is not implemented, then - * {@link MifareUltralightImpl} will never be enumerated in {@link TagImpl#getTechList}. - * If it is enumerated, then all {@link MifareUltralightImpl} I/O operations will be supported. - * In either case, {@link NfcAImpl} will also be enumerated on the tag, - * because all MIFARE Ultralight tags are also {@link NfcAImpl} tags. - * - *

    Note: Methods that perform I/O operations - * require the {@link android.Manifest.permission#NFC} permission. - */ -public final class MifareUltralightImpl extends MifareUltralight { - - /** @hide */ - public static final String EXTRA_IS_UL_C = "isulc"; - - private static final String TAG = "NFC"; - - private static final int NXP_MANUFACTURER_ID = 0x04; - private static final int MAX_PAGE_COUNT = 256; - - private int mType; - - private BasicTagTechnologyImpl delegate; - - public MifareUltralightImpl(TagImpl tag) throws RemoteException { - this.delegate = new BasicTagTechnologyImpl(tag, TagTechnology.MIFARE_ULTRALIGHT); - - // Check if this could actually be a MIFARE - NfcA a = NfcAImpl.get(tag); - - mType = TYPE_UNKNOWN; - - if (a.getSak() == 0x00 && tag.getId()[0] == NXP_MANUFACTURER_ID) { - Bundle extras = tag.getTechExtras(TagTechnology.MIFARE_ULTRALIGHT); - if (extras.getBoolean(EXTRA_IS_UL_C)) { - mType = TYPE_ULTRALIGHT_C; - } else { - mType = TYPE_ULTRALIGHT; - } - } - } - - /** - * Return the MIFARE Ultralight type of the tag. - *

    One of {@link #TYPE_ULTRALIGHT} or {@link #TYPE_ULTRALIGHT_C} or - * {@link #TYPE_UNKNOWN}. - *

    Depending on how the tag has been formatted, it can be impossible - * to accurately classify between original MIFARE Ultralight and - * Ultralight C. So treat this method as a hint. - *

    Does not cause any RF activity and does not block. - * - * @return the type - */ - @Override - public int getType() { - return mType; - } - - /** - * Read 4 pages (16 bytes). - * - *

    The MIFARE Ultralight protocol always reads 4 pages at a time, to - * reduce the number of commands required to read an entire tag. - *

    If a read spans past the last readable block, then the tag will - * return pages that have been wrapped back to the first blocks. MIFARE - * Ultralight tags have readable blocks 0x00 through 0x0F. So a read to - * block offset 0x0E would return blocks 0x0E, 0x0F, 0x00, 0x01. MIFARE - * Ultralight C tags have readable blocks 0x00 through 0x2B. So a read to - * block 0x2A would return blocks 0x2A, 0x2B, 0x00, 0x01. - * - *

    This is an I/O operation and will block until complete. It must - * not be called from the main application thread. A blocked call will be canceled with - * {@link IOException} if {@link #close} is called from another thread. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param pageOffset index of first page to read, starting from 0 - * @return 4 pages (16 bytes) - * @throws android.nfc.TagLostException if the tag leaves the field - * @throws IOException if there is an I/O failure, or the operation is canceled - */ - @Override - public byte[] readPages(int pageOffset) throws IOException { - validatePageIndex(pageOffset); - delegate.checkConnected(); - - byte[] cmd = { 0x30, (byte) pageOffset}; - return delegate.transceive(cmd, false); - } - - /** - * Write 1 page (4 bytes). - * - *

    The MIFARE Ultralight protocol always writes 1 page at a time, to - * minimize EEPROM write cycles. - * - *

    This is an I/O operation and will block until complete. It must - * not be called from the main application thread. A blocked call will be canceled with - * {@link IOException} if {@link #close} is called from another thread. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param pageOffset index of page to write, starting from 0 - * @param data 4 bytes to write - * @throws android.nfc.TagLostException if the tag leaves the field - * @throws IOException if there is an I/O failure, or the operation is canceled - */ - @Override - public void writePage(int pageOffset, byte[] data) throws IOException { - validatePageIndex(pageOffset); - delegate.checkConnected(); - - byte[] cmd = new byte[data.length + 2]; - cmd[0] = (byte) 0xA2; - cmd[1] = (byte) pageOffset; - System.arraycopy(data, 0, cmd, 2, data.length); - - delegate.transceive(cmd, false); - } - - /** - * Send raw NfcA data to a tag and receive the response. - * - *

    This is equivalent to connecting to this tag via {@link NfcAImpl} - * and calling {@link NfcAImpl#transceive}. Note that all MIFARE Classic - * tags are based on {@link NfcAImpl} technology. - * - *

    Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes - * that can be sent with {@link #transceive}. - * - *

    This is an I/O operation and will block until complete. It must - * not be called from the main application thread. A blocked call will be canceled with - * {@link IOException} if {@link #close} is called from another thread. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @see NfcAImpl#transceive - */ - @Override - public byte[] transceive(byte[] data) throws IOException { - return delegate.transceive(data, true); - } - - /** - * Return the maximum number of bytes that can be sent with {@link #transceive}. - * @return the maximum number of bytes that can be sent with {@link #transceive}. - */ - @Override - public int getMaxTransceiveLength() { - return delegate.getMaxTransceiveLengthInternal(); - } - - /** - * Set the {@link #transceive} timeout in milliseconds. - * - *

    The timeout only applies to {@link #transceive} on this object, - * and is reset to a default value when {@link #close} is called. - * - *

    Setting a longer timeout may be useful when performing - * transactions that require a long processing time on the tag - * such as key generation. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param timeout timeout value in milliseconds - */ - @Override - public void setTimeout(int timeout) { - try { - int err = delegate.getTag().getTagService().setTimeout( - TagTechnology.MIFARE_ULTRALIGHT, timeout); - if (err != ErrorCodes.SUCCESS) { - throw new IllegalArgumentException("The supplied timeout is not valid"); - } - } catch (RemoteException e) { - Log.e(TAG, "NFC service dead", e); - } - } - - /** - * Get the current {@link #transceive} timeout in milliseconds. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @return timeout value in milliseconds - */ - @Override - public int getTimeout() { - try { - return delegate.getTag().getTagService().getTimeout(TagTechnology.MIFARE_ULTRALIGHT); - } catch (RemoteException e) { - Log.e(TAG, "NFC service dead", e); - return 0; - } - } - - private static void validatePageIndex(int pageIndex) { - // Do not be too strict on upper bounds checking, since some cards - // may have more addressable memory than they report. - // Note that issuing a command to an out-of-bounds block is safe - the - // tag will wrap the read to an addressable area. This validation is a - // helper to guard against obvious programming mistakes. - if (pageIndex < 0 || pageIndex >= MAX_PAGE_COUNT) { - throw new IndexOutOfBoundsException("page out of bounds: " + pageIndex); - } - } - - @Override - public Tag getTag() { - return delegate.getTag(); - } - - @Override - public void connect() throws IOException { - delegate.connect(); - } - - @Override - public void close() throws IOException { - delegate.close(); - } - - @Override - public boolean isConnected() { - return delegate.isConnected(); - } - - -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/MifareUltralightWrapper.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/MifareUltralightWrapper.java deleted file mode 100644 index 872d85c..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/MifareUltralightWrapper.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.github.skjolber.android.nfc.tech; - -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagWrapper; - -import java.io.IOException; - -public class MifareUltralightWrapper extends MifareUltralight { - - protected android.nfc.tech.MifareUltralight delegate; - - public MifareUltralightWrapper(android.nfc.tech.MifareUltralight delegate) { - this.delegate = delegate; - } - - @Override - public int getType() { - return delegate.getType(); - } - - @Override - public byte[] readPages(int pageOffset) throws IOException { - return delegate.readPages(pageOffset); - } - - @Override - public void writePage(int pageOffset, byte[] data) throws IOException { - delegate.writePage(pageOffset, data); - } - - @Override - public byte[] transceive(byte[] data) throws IOException { - return delegate.transceive(data); - } - - @Override - public int getMaxTransceiveLength() { - return delegate.getMaxTransceiveLength(); - } - - @Override - public void setTimeout(int timeout) { - delegate.setTimeout(timeout); - } - - @Override - public int getTimeout() { - return delegate.getTimeout(); - } - - @Override - public Tag getTag() { - return new TagWrapper(delegate.getTag()); - } - - @Override - public void connect() throws IOException { - delegate.connect(); - } - - @Override - public void close() throws IOException { - delegate.close(); - } - - @Override - public boolean isConnected() { - return delegate.isConnected(); - } -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/Ndef.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/Ndef.java deleted file mode 100644 index f91791a..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/Ndef.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.github.skjolber.android.nfc.tech; - -import android.nfc.FormatException; -import android.nfc.NdefMessage; -import android.os.RemoteException; - -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagImpl; -import com.github.skjolber.android.nfc.TagWrapper; - -import java.io.IOException; - -public abstract class Ndef implements BasicTagTechnology { - /** @hide */ - public static final int NDEF_MODE_READ_ONLY = 1; - /** @hide */ - public static final int NDEF_MODE_READ_WRITE = 2; - /** @hide */ - public static final int NDEF_MODE_UNKNOWN = 3; - /** @hide */ - public static final String EXTRA_NDEF_MSG = "ndefmsg"; - /** @hide */ - public static final String EXTRA_NDEF_MAXLENGTH = "ndefmaxlength"; - /** @hide */ - public static final String EXTRA_NDEF_CARDSTATE = "ndefcardstate"; - /** @hide */ - public static final String EXTRA_NDEF_TYPE = "ndeftype"; - /** @hide */ - public static final int TYPE_OTHER = -1; - /** @hide */ - public static final int TYPE_1 = 1; - /** @hide */ - public static final int TYPE_2 = 2; - /** @hide */ - public static final int TYPE_3 = 3; - /** @hide */ - public static final int TYPE_4 = 4; - /** @hide */ - public static final int TYPE_MIFARE_CLASSIC = 101; - /** @hide */ - public static final int TYPE_ICODE_SLI = 102; - /** @hide */ - public static final String UNKNOWN = "android.ndef.unknown"; - /** NFC Forum Tag Type 1 */ - public static final String NFC_FORUM_TYPE_1 = "org.nfcforum.ndef.type1"; - /** NFC Forum Tag Type 2 */ - public static final String NFC_FORUM_TYPE_2 = "org.nfcforum.ndef.type2"; - /** NFC Forum Tag Type 4 */ - public static final String NFC_FORUM_TYPE_3 = "org.nfcforum.ndef.type3"; - /** NFC Forum Tag Type 4 */ - public static final String NFC_FORUM_TYPE_4 = "org.nfcforum.ndef.type4"; - /** NDEF on MIFARE Classic */ - public static final String MIFARE_CLASSIC = "com.nxp.ndef.mifareclassic"; - /** - * NDEF on iCODE SLI - * @hide - */ - public static final String ICODE_SLI = "com.nxp.ndef.icodesli"; - - - /** - * Get an instance of {@link NdefImpl} for the given tag. - * - *

    Returns null if {@link NdefImpl} was not enumerated in {@link TagImpl#getTechList}. - * This indicates the tag is not NDEF formatted, or that this tag - * is NDEF formatted but under a vendor specification that this Android - * device does not implement. - * - *

    Does not cause any RF activity and does not block. - * - * @param tag an NDEF compatible tag - * @return Ndef object - */ - public static Ndef get(Tag tag) { - if(tag instanceof TagImpl) { - TagImpl tagImpl = (TagImpl)tag; - if (!tagImpl.hasTech(TagTechnology.NDEF)) return null; - try { - return new NdefImpl(tagImpl); - } catch (RemoteException e) { - return null; - } - } else if(tag instanceof TagWrapper) { - TagWrapper delegate = (TagWrapper)tag; - return new NdefWrapper(android.nfc.tech.Ndef.get(delegate.getDelegate())); - } else { - throw new IllegalArgumentException(); - } - } - - - public abstract NdefMessage getCachedNdefMessage(); - - public abstract String getType(); - - public abstract int getMaxSize(); - - public abstract boolean isWritable(); - - public abstract NdefMessage getNdefMessage() throws IOException, FormatException; - - public abstract void writeNdefMessage(NdefMessage msg) throws IOException, FormatException; - - public abstract boolean canMakeReadOnly(); - - public abstract boolean makeReadOnly() throws IOException; -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NdefFormatable.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NdefFormatable.java deleted file mode 100644 index b06ebf0..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NdefFormatable.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.github.skjolber.android.nfc.tech; - -import com.github.skjolber.android.nfc.ErrorCodes; -import com.github.skjolber.android.nfc.INfcTag; -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagImpl; -import com.github.skjolber.android.nfc.TagWrapper; - -import android.nfc.FormatException; -import android.nfc.NdefMessage; -import android.os.RemoteException; -import android.util.Log; - -import java.io.IOException; - -/** - * Provide access to NDEF format operations on a {@link TagImpl}. - * - *

    Acquire a {@link NdefFormatable} object using {@link #get}. - * - *

    Android devices with NFC must only enumerate and implement this - * class for tags for which it can format to NDEF. - * - *

    Unfortunately the procedures to convert unformated tags to NDEF formatted - * tags are not specified by NFC Forum, and are not generally well-known. So - * there is no mandatory set of tags for which all Android devices with NFC - * must support {@link NdefFormatable}. - * - *

    Note: Methods that perform I/O operations - * require the {@link android.Manifest.permission#NFC} permission. - */ -public abstract class NdefFormatable implements BasicTagTechnology { - - - /** - * Get an instance of {@link NdefFormatable} for the given tag. - *

    Does not cause any RF activity and does not block. - *

    Returns null if {@link NdefFormatable} was not enumerated in {@link Tag#getTechList}. - * This indicates the tag is not NDEF formatable by this Android device. - * - * @param tag an NDEF formatable tag - * @return NDEF formatable object - */ - public static NdefFormatable get(Tag tag) { - if(tag instanceof TagImpl) { - TagImpl tagImpl = (TagImpl)tag; - if (!tagImpl.hasTech(TagTechnology.NDEF_FORMATABLE)) return null; - try { - return new NdefFormatableImpl(tagImpl); - } catch (RemoteException e) { - return null; - } - } else if(tag instanceof TagWrapper) { - TagWrapper delegate = (TagWrapper)tag; - return new NdefFormattableWrapper(android.nfc.tech.NdefFormatable.get(delegate.getDelegate())); - } else { - throw new IllegalArgumentException(); - } - } - - /** - * Format a tag as NDEF, and write a {@link NdefMessage}. - * - *

    This is a multi-step process, an IOException is thrown - * if any one step fails. - *

    The card is left in a read-write state after this operation. - * - *

    This is an I/O operation and will block until complete. It must - * not be called from the main application thread. A blocked call will be canceled with - * {@link IOException} if {@link #close} is called from another thread. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param firstMessage the NDEF message to write after formatting, can be null - * @throws android.nfc.TagLostException if the tag leaves the field - * @throws IOException if there is an I/O failure, or the operation is canceled - * @throws FormatException if the NDEF Message to write is malformed - */ - public abstract void format(NdefMessage firstMessage) throws IOException, FormatException; - - /** - * Formats a tag as NDEF, write a {@link NdefMessage}, and make read-only. - * - *

    This is a multi-step process, an IOException is thrown - * if any one step fails. - *

    The card is left in a read-only state if this method returns successfully. - * - *

    This is an I/O operation and will block until complete. It must - * not be called from the main application thread. A blocked call will be canceled with - * {@link IOException} if {@link #close} is called from another thread. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param firstMessage the NDEF message to write after formatting - * @throws android.nfc.TagLostException if the tag leaves the field - * @throws IOException if there is an I/O failure, or the operation is canceled - * @throws FormatException if the NDEF Message to write is malformed - */ - public abstract void formatReadOnly(NdefMessage firstMessage) throws IOException, FormatException; -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NdefFormatableImpl.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NdefFormatableImpl.java deleted file mode 100644 index 84159dd..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NdefFormatableImpl.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.github.skjolber.android.nfc.tech; - -import android.nfc.FormatException; -import android.nfc.NdefMessage; -import android.os.RemoteException; -import android.util.Log; - -import com.github.skjolber.android.nfc.ErrorCodes; -import com.github.skjolber.android.nfc.INfcTag; -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagImpl; - -import java.io.IOException; - -/** - * Provide access to NDEF format operations on a {@link TagImpl}. - * - *

    Acquire a {@link NdefFormatableImpl} object using get. - * - *

    Android devices with NFC must only enumerate and implement this - * class for tags for which it can format to NDEF. - * - *

    Unfortunately the procedures to convert unformated tags to NDEF formatted - * tags are not specified by NFC Forum, and are not generally well-known. So - * there is no mandatory set of tags for which all Android devices with NFC - * must support {@link NdefFormatableImpl}. - * - *

    Note: Methods that perform I/O operations - * require the {@link android.Manifest.permission#NFC} permission. - */ -public final class NdefFormatableImpl extends NdefFormatable { - private static final String TAG = "NFC"; - - private BasicTagTechnologyImpl delegate; - - public NdefFormatableImpl(TagImpl tag) throws RemoteException { - this.delegate = new BasicTagTechnologyImpl(tag, TagTechnology.NDEF_FORMATABLE); - } - - /** - * Format a tag as NDEF, and write a {@link NdefMessage}. - * - *

    This is a multi-step process, an IOException is thrown - * if any one step fails. - *

    The card is left in a read-write state after this operation. - * - *

    This is an I/O operation and will block until complete. It must - * not be called from the main application thread. A blocked call will be canceled with - * {@link IOException} if {@link #close} is called from another thread. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param firstMessage the NDEF message to write after formatting, can be null - * @throws android.nfc.TagLostException if the tag leaves the field - * @throws IOException if there is an I/O failure, or the operation is canceled - * @throws FormatException if the NDEF Message to write is malformed - */ - public void format(NdefMessage firstMessage) throws IOException, FormatException { - format(firstMessage, false); - } - - /** - * Formats a tag as NDEF, write a {@link NdefMessage}, and make read-only. - * - *

    This is a multi-step process, an IOException is thrown - * if any one step fails. - *

    The card is left in a read-only state if this method returns successfully. - * - *

    This is an I/O operation and will block until complete. It must - * not be called from the main application thread. A blocked call will be canceled with - * {@link IOException} if {@link #close} is called from another thread. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param firstMessage the NDEF message to write after formatting - * @throws android.nfc.TagLostException if the tag leaves the field - * @throws IOException if there is an I/O failure, or the operation is canceled - * @throws FormatException if the NDEF Message to write is malformed - */ - public void formatReadOnly(NdefMessage firstMessage) throws IOException, FormatException { - format(firstMessage, true); - } - - /*package*/ void format(NdefMessage firstMessage, boolean makeReadOnly) throws IOException, - FormatException { - delegate.checkConnected(); - - try { - int serviceHandle = delegate.getTag().getServiceHandle(); - INfcTag tagService = delegate.getTag().getTagService(); - int errorCode = tagService.formatNdef(serviceHandle, MifareClassic.KEY_DEFAULT); - switch (errorCode) { - case ErrorCodes.SUCCESS: - break; - case ErrorCodes.ERROR_IO: - throw new IOException(); - case ErrorCodes.ERROR_INVALID_PARAM: - throw new FormatException(); - default: - // Should not happen - throw new IOException(); - } - // Now check and see if the format worked - if (!tagService.isNdef(serviceHandle)) { - throw new IOException(); - } - - // Write a message, if one was provided - if (firstMessage != null) { - errorCode = tagService.ndefWrite(serviceHandle, firstMessage); - switch (errorCode) { - case ErrorCodes.SUCCESS: - break; - case ErrorCodes.ERROR_IO: - throw new IOException(); - case ErrorCodes.ERROR_INVALID_PARAM: - throw new FormatException(); - default: - // Should not happen - throw new IOException(); - } - } - - // optionally make read-only - if (makeReadOnly) { - errorCode = tagService.ndefMakeReadOnly(serviceHandle); - switch (errorCode) { - case ErrorCodes.SUCCESS: - break; - case ErrorCodes.ERROR_IO: - throw new IOException(); - case ErrorCodes.ERROR_INVALID_PARAM: - throw new IOException(); - default: - // Should not happen - throw new IOException(); - } - } - } catch (RemoteException e) { - Log.e(TAG, "NFC service dead", e); - } - } - - @Override - public Tag getTag() { - return delegate.getTag(); - } - - @Override - public void connect() throws IOException { - delegate.connect(); - } - - @Override - public void close() throws IOException { - delegate.close(); - } - - @Override - public boolean isConnected() { - return delegate.isConnected(); - } - -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NdefFormattableWrapper.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NdefFormattableWrapper.java deleted file mode 100644 index 19132a7..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NdefFormattableWrapper.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.github.skjolber.android.nfc.tech; - -import android.nfc.FormatException; -import android.nfc.NdefMessage; - -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagWrapper; - -import java.io.IOException; - -public class NdefFormattableWrapper extends NdefFormatable { - - protected android.nfc.tech.NdefFormatable delegate; - - public NdefFormattableWrapper(android.nfc.tech.NdefFormatable delegate) { - this.delegate = delegate; - } - - @Override - public void format(NdefMessage firstMessage) throws IOException, FormatException { - delegate.format(firstMessage); - } - - @Override - public void formatReadOnly(NdefMessage firstMessage) throws IOException, FormatException { - delegate.formatReadOnly(firstMessage); - } - - @Override - public Tag getTag() { - return new TagWrapper(delegate.getTag()); - } - - @Override - public void connect() throws IOException { - delegate.connect(); - } - - @Override - public void close() throws IOException { - delegate.close(); - } - - @Override - public boolean isConnected() { - return delegate.isConnected(); - } - -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NdefImpl.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NdefImpl.java deleted file mode 100644 index fad8246..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NdefImpl.java +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.github.skjolber.android.nfc.tech; - -import com.github.skjolber.android.nfc.ErrorCodes; -import com.github.skjolber.android.nfc.INfcTag; -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagWrapper; -import com.github.skjolber.android.nfc.TagImpl; - -import android.nfc.FormatException; -import android.nfc.NdefMessage; -import android.nfc.TagLostException; -import android.os.Bundle; -import android.os.RemoteException; -import android.util.Log; - -import java.io.IOException; - -/** - * Provides access to NDEF content and operations on a {@link TagImpl}. - * - *

    Acquire a {@link NdefImpl} object using {@link #get}. - * - *

    NDEF is an NFC Forum data format. The data formats are implemented in - * {@link android.nfc.NdefMessage} and - * {@link android.nfc.NdefRecord}. This class provides methods to - * retrieve and modify the {@link android.nfc.NdefMessage} - * on a tag. - * - *

    There are currently four NFC Forum standardized tag types that can be - * formatted to contain NDEF data. - *

      - *
    • NFC Forum Type 1 Tag ({@link #NFC_FORUM_TYPE_1}), such as the Innovision Topaz - *
    • NFC Forum Type 2 Tag ({@link #NFC_FORUM_TYPE_2}), such as the NXP MIFARE Ultralight - *
    • NFC Forum Type 3 Tag ({@link #NFC_FORUM_TYPE_3}), such as Sony Felica - *
    • NFC Forum Type 4 Tag ({@link #NFC_FORUM_TYPE_4}), such as NXP MIFARE Desfire - *
    - * It is mandatory for all Android devices with NFC to correctly enumerate - * {@link NdefImpl} on NFC Forum Tag Types 1-4, and implement all NDEF operations - * as defined in this class. - * - *

    Some vendors have their own well defined specifications for storing NDEF data - * on tags that do not fall into the above categories. Android devices with NFC - * should enumerate and implement {@link NdefImpl} under these vendor specifications - * where possible, but it is not mandatory. {@link #getType} returns a String - * describing this specification, for example {@link #MIFARE_CLASSIC} is - * com.nxp.ndef.mifareclassic. - * - *

    Android devices that support MIFARE Classic must also correctly - * implement {@link NdefImpl} on MIFARE Classic tags formatted to NDEF. - * - *

    For guaranteed compatibility across all Android devices with NFC, it is - * recommended to use NFC Forum Types 1-4 in new deployments of NFC tags - * with NDEF payload. Vendor NDEF formats will not work on all Android devices. - * - *

    Note: Methods that perform I/O operations - * require the {@link android.Manifest.permission#NFC} permission. - */ -public final class NdefImpl extends Ndef { - private static final String TAG = "NFC"; - - private final int mMaxNdefSize; - private final int mCardState; - private final NdefMessage mNdefMsg; - private final int mNdefType; - - /** - * Internal constructor, to be used by NfcAdapter - * @hide - */ - private BasicTagTechnologyImpl delegate; - - public NdefImpl(TagImpl tag) throws RemoteException { - this.delegate = new BasicTagTechnologyImpl(tag, TagTechnology.NDEF); - - Bundle extras = tag.getTechExtras(TagTechnology.NDEF); - if (extras != null) { - mMaxNdefSize = extras.getInt(EXTRA_NDEF_MAXLENGTH); - mCardState = extras.getInt(EXTRA_NDEF_CARDSTATE); - mNdefMsg = extras.getParcelable(EXTRA_NDEF_MSG); - mNdefType = extras.getInt(EXTRA_NDEF_TYPE); - } else { - throw new NullPointerException("NDEF tech extras are null."); - } - - } - - /** - * Get the {@link NdefMessage} that was read from the tag at discovery time. - * - *

    If the NDEF Message is modified by an I/O operation then it - * will not be updated here, this function only returns what was discovered - * when the tag entered the field. - *

    Note that this method may return null if the tag was in the - * INITIALIZED state as defined by NFC Forum, as in this state the - * tag is formatted to support NDEF but does not contain a message yet. - *

    Does not cause any RF activity and does not block. - * @return NDEF Message read from the tag at discovery time, can be null - */ - @Override - public NdefMessage getCachedNdefMessage() { - return mNdefMsg; - } - - /** - * Get the NDEF tag type. - * - *

    Returns one of {@link #NFC_FORUM_TYPE_1}, {@link #NFC_FORUM_TYPE_2}, - * {@link #NFC_FORUM_TYPE_3}, {@link #NFC_FORUM_TYPE_4}, - * {@link #MIFARE_CLASSIC} or another NDEF tag type that has not yet been - * formalized in this Android API. - * - *

    Does not cause any RF activity and does not block. - * - * @return a string representing the NDEF tag type - */ - @Override - public String getType() { - switch (mNdefType) { - case TYPE_1: - return NFC_FORUM_TYPE_1; - case TYPE_2: - return NFC_FORUM_TYPE_2; - case TYPE_3: - return NFC_FORUM_TYPE_3; - case TYPE_4: - return NFC_FORUM_TYPE_4; - case TYPE_MIFARE_CLASSIC: - return Ndef.MIFARE_CLASSIC; - case TYPE_ICODE_SLI: - return ICODE_SLI; - default: - return UNKNOWN; - } - } - - /** - * Get the maximum NDEF message size in bytes. - * - *

    Does not cause any RF activity and does not block. - * - * @return size in bytes - */ - @Override - public int getMaxSize() { - return mMaxNdefSize; - } - - /** - * Determine if the tag is writable. - * - *

    NFC Forum tags can be in read-only or read-write states. - * - *

    Does not cause any RF activity and does not block. - * - *

    Requires {@link android.Manifest.permission#NFC} permission. - * - * @return true if the tag is writable - */ - @Override - public boolean isWritable() { - return (mCardState == NDEF_MODE_READ_WRITE); - } - - /** - * Read the current {@link android.nfc.NdefMessage} on this tag. - * - *

    This always reads the current NDEF Message stored on the tag. - * - *

    Note that this method may return null if the tag was in the - * INITIALIZED state as defined by NFC Forum, as in that state the - * tag is formatted to support NDEF but does not contain a message yet. - * - *

    This is an I/O operation and will block until complete. It must - * not be called from the main application thread. A blocked call will be canceled with - * {@link IOException} if {@link #close} is called from another thread. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @return the NDEF Message, can be null - * @throws TagLostException if the tag leaves the field - * @throws IOException if there is an I/O failure, or the operation is canceled - * @throws FormatException if the NDEF Message on the tag is malformed - */ - @Override - public NdefMessage getNdefMessage() throws IOException, FormatException { - delegate.checkConnected(); - - try { - INfcTag tagService = delegate.getTag().getTagService(); - if (tagService == null) { - throw new IOException("Mock tags don't support this operation."); - } - int serviceHandle = delegate.getTag().getServiceHandle(); - if (tagService.isNdef(serviceHandle)) { - NdefMessage msg = tagService.ndefRead(serviceHandle); - if (msg == null && !tagService.isPresent(serviceHandle)) { - throw new TagLostException(); - } - return msg; - } else if (!tagService.isPresent(serviceHandle)) { - throw new TagLostException(); - } else { - return null; - } - } catch (RemoteException e) { - Log.e(TAG, "NFC service dead", e); - return null; - } - } - - /** - * Overwrite the {@link NdefMessage} on this tag. - * - *

    This is an I/O operation and will block until complete. It must - * not be called from the main application thread. A blocked call will be canceled with - * {@link IOException} if {@link #close} is called from another thread. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param msg the NDEF Message to write, must not be null - * @throws TagLostException if the tag leaves the field - * @throws IOException if there is an I/O failure, or the operation is canceled - * @throws FormatException if the NDEF Message to write is malformed - */ - @Override - public void writeNdefMessage(NdefMessage msg) throws IOException, FormatException { - delegate.checkConnected(); - - try { - INfcTag tagService = delegate.getTag().getTagService(); - if (tagService == null) { - throw new IOException("Mock tags don't support this operation."); - } - int serviceHandle = delegate.getTag().getServiceHandle(); - if (tagService.isNdef(serviceHandle)) { - int errorCode = tagService.ndefWrite(serviceHandle, msg); - switch (errorCode) { - case ErrorCodes.SUCCESS: - break; - case ErrorCodes.ERROR_IO: - throw new IOException(); - case ErrorCodes.ERROR_INVALID_PARAM: - throw new FormatException(); - default: - // Should not happen - throw new IOException(); - } - } - else { - throw new IOException("Tag is not ndef"); - } - } catch (RemoteException e) { - Log.e(TAG, "NFC service dead", e); - } - } - - /** - * Indicates whether a tag can be made read-only with {@link #makeReadOnly()}. - * - *

    Does not cause any RF activity and does not block. - * - * @return true if it is possible to make this tag read-only - */ - @Override - public boolean canMakeReadOnly() { - INfcTag tagService = delegate.getTag().getTagService(); - if (tagService == null) { - return false; - } - try { - return tagService.canMakeReadOnly(mNdefType); - } catch (RemoteException e) { - Log.e(TAG, "NFC service dead", e); - return false; - } - } - - /** - * Make a tag read-only. - * - *

    This sets the CC field to indicate the tag is read-only, - * and where possible permanently sets the lock bits to prevent - * any further modification of the memory. - *

    This is a one-way process and cannot be reverted! - * - *

    This is an I/O operation and will block until complete. It must - * not be called from the main application thread. A blocked call will be canceled with - * {@link IOException} if {@link #close} is called from another thread. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @return true on success, false if it is not possible to make this tag read-only - * @throws TagLostException if the tag leaves the field - * @throws IOException if there is an I/O failure, or the operation is canceled - */ - @Override - public boolean makeReadOnly() throws IOException { - delegate.checkConnected(); - - try { - INfcTag tagService = delegate.getTag().getTagService(); - if (tagService == null) { - return false; - } - if (tagService.isNdef(delegate.getTag().getServiceHandle())) { - int errorCode = tagService.ndefMakeReadOnly(delegate.getTag().getServiceHandle()); - switch (errorCode) { - case ErrorCodes.SUCCESS: - return true; - case ErrorCodes.ERROR_IO: - throw new IOException(); - case ErrorCodes.ERROR_INVALID_PARAM: - return false; - default: - // Should not happen - throw new IOException(); - } - } - else { - throw new IOException("Tag is not ndef"); - } - } catch (RemoteException e) { - Log.e(TAG, "NFC service dead", e); - return false; - } - } - - @Override - public Tag getTag() { - return delegate.getTag(); - } - - @Override - public void connect() throws IOException { - delegate.connect(); - } - - @Override - public void close() throws IOException { - delegate.close(); - } - - @Override - public boolean isConnected() { - return delegate.isConnected(); - } - -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NdefWrapper.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NdefWrapper.java deleted file mode 100644 index 7d77588..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NdefWrapper.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.github.skjolber.android.nfc.tech; - -import android.nfc.FormatException; -import android.nfc.NdefMessage; - -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagWrapper; - -import java.io.IOException; - -public class NdefWrapper extends Ndef { - - protected android.nfc.tech.Ndef delegate; - - public NdefWrapper(android.nfc.tech.Ndef delegate) { - this.delegate = delegate; - } - - @Override - public NdefMessage getCachedNdefMessage() { - return delegate.getCachedNdefMessage(); - } - - @Override - public String getType() { - return delegate.getType(); - } - - @Override - public int getMaxSize() { - return delegate.getMaxSize(); - } - - @Override - public boolean isWritable() { - return delegate.isWritable(); - } - - @Override - public NdefMessage getNdefMessage() throws IOException, FormatException { - return delegate.getNdefMessage(); - } - - @Override - public void writeNdefMessage(NdefMessage msg) throws IOException, FormatException { - delegate.writeNdefMessage(msg); - } - - @Override - public boolean canMakeReadOnly() { - return delegate.canMakeReadOnly(); - } - - @Override - public boolean makeReadOnly() throws IOException { - return delegate.makeReadOnly(); - } - - - @Override - public Tag getTag() { - return new TagWrapper(delegate.getTag()); - } - - @Override - public void connect() throws IOException { - delegate.connect(); - } - - @Override - public void close() throws IOException { - delegate.close(); - } - - @Override - public boolean isConnected() { - return delegate.isConnected(); - } -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcA.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcA.java deleted file mode 100644 index c5e5895..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcA.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.github.skjolber.android.nfc.tech; - -import android.os.RemoteException; - -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagImpl; -import com.github.skjolber.android.nfc.TagWrapper; - -import java.io.IOException; - -public abstract class NfcA implements BasicTagTechnology { - - String EXTRA_SAK = "sak"; - String EXTRA_ATQA = "atqa"; - - /** - * Get an instance of {@link NfcAImpl} for the given tag. - *

    Returns null if {@link NfcAImpl} was not enumerated in {@link TagImpl#getTechList}. - * This indicates the tag does not support NFC-A. - *

    Does not cause any RF activity and does not block. - * - * @param tag an NFC-A compatible tag - * @return NFC-A object - */ - public static NfcA get(Tag tag) { - if(tag instanceof TagImpl) { - TagImpl tagImpl = (TagImpl)tag; - if (!tagImpl.hasTech(TagTechnology.NFC_A)) return null; - try { - return new NfcAImpl(tagImpl); - } catch (RemoteException e) { - return null; - } - } else if(tag instanceof TagWrapper) { - TagWrapper delegate = (TagWrapper)tag; - return new NfcAWrapper(android.nfc.tech.NfcA.get(delegate.getDelegate())); - } else { - throw new IllegalArgumentException(); - } - } - - public abstract byte[] getAtqa(); - - public abstract short getSak(); - - public abstract byte[] transceive(byte[] data) throws IOException; - - public abstract int getMaxTransceiveLength(); - - public abstract void setTimeout(int timeout); - - public abstract int getTimeout(); -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcAImpl.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcAImpl.java deleted file mode 100644 index 59247e5..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcAImpl.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.github.skjolber.android.nfc.tech; - -import com.github.skjolber.android.nfc.ErrorCodes; -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagWrapper; -import com.github.skjolber.android.nfc.TagImpl; - -import android.os.Bundle; -import android.os.RemoteException; -import android.util.Log; - -import java.io.IOException; - -/** - * Provides access to NFC-A (ISO 14443-3A) properties and I/O operations on a {@link TagImpl}. - * - *

    Acquire a {@link NfcAImpl} object using {@link #get}. - *

    The primary NFC-A I/O operation is {@link #transceive}. Applications must - * implement their own protocol stack on top of {@link #transceive}. - * - *

    Note: Methods that perform I/O operations - * require the {@link android.Manifest.permission#NFC} permission. - */ -public final class NfcAImpl extends NfcA { - private static final String TAG = "NFC"; - - private short mSak; - private byte[] mAtqa; - - private BasicTagTechnologyImpl delegate; - - public NfcAImpl(TagImpl tag) throws RemoteException { - this.delegate = new BasicTagTechnologyImpl(tag, TagTechnology.NFC_A); - - Bundle extras = tag.getTechExtras(TagTechnology.NFC_A); - mSak = extras.getShort(EXTRA_SAK); - mAtqa = extras.getByteArray(EXTRA_ATQA); - } - - /** - * Return the ATQA/SENS_RES bytes from tag discovery. - * - *

    Does not cause any RF activity and does not block. - * - * @return ATQA/SENS_RES bytes - */ - @Override - public byte[] getAtqa() { - return mAtqa; - } - - /** - * Return the SAK/SEL_RES bytes from tag discovery. - * - *

    Does not cause any RF activity and does not block. - * - * @return SAK bytes - */ - @Override - public short getSak() { - return mSak; - } - - /** - * Send raw NFC-A commands to the tag and receive the response. - * - *

    Applications must not append the EoD (CRC) to the payload, - * it will be automatically calculated. - *

    Applications must only send commands that are complete bytes, - * for example a SENS_REQ is not possible (these are used to - * manage tag polling and initialization). - * - *

    Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes - * that can be sent with {@link #transceive}. - * - *

    This is an I/O operation and will block until complete. It must - * not be called from the main application thread. A blocked call will be canceled with - * {@link IOException} if {@link #close} is called from another thread. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param data bytes to send - * @return bytes received in response - * @throws android.nfc.TagLostException if the tag leaves the field - * @throws IOException if there is an I/O failure, or this operation is canceled - */ - @Override - public byte[] transceive(byte[] data) throws IOException { - return delegate.transceive(data, true); - } - - /** - * Return the maximum number of bytes that can be sent with {@link #transceive}. - * @return the maximum number of bytes that can be sent with {@link #transceive}. - */ - @Override - public int getMaxTransceiveLength() { - return delegate.getMaxTransceiveLengthInternal(); - } - - /** - * Set the {@link #transceive} timeout in milliseconds. - * - *

    The timeout only applies to {@link #transceive} on this object, - * and is reset to a default value when {@link #close} is called. - * - *

    Setting a longer timeout may be useful when performing - * transactions that require a long processing time on the tag - * such as key generation. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param timeout timeout value in milliseconds - */ - @Override - public void setTimeout(int timeout) { - try { - int err = delegate.getTag().getTagService().setTimeout(TagTechnology.NFC_A, timeout); - if (err != ErrorCodes.SUCCESS) { - throw new IllegalArgumentException("The supplied timeout is not valid"); - } - } catch (RemoteException e) { - Log.e(TAG, "NFC service dead", e); - } - } - - /** - * Get the current {@link #transceive} timeout in milliseconds. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @return timeout value in milliseconds - */ - @Override - public int getTimeout() { - try { - return delegate.getTag().getTagService().getTimeout(TagTechnology.NFC_A); - } catch (RemoteException e) { - Log.e(TAG, "NFC service dead", e); - return 0; - } - } - - @Override - public Tag getTag() { - return delegate.getTag(); - } - - @Override - public void connect() throws IOException { - delegate.connect(); - } - - @Override - public void close() throws IOException { - delegate.close(); - } - - @Override - public boolean isConnected() { - return delegate.isConnected(); - } - -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcAWrapper.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcAWrapper.java deleted file mode 100644 index c133b17..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcAWrapper.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.github.skjolber.android.nfc.tech; - -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagWrapper; - -import java.io.IOException; - -public class NfcAWrapper extends NfcA { - - protected android.nfc.tech.NfcA delegate; - - public NfcAWrapper(android.nfc.tech.NfcA delegate) { - this.delegate = delegate; - } - - @Override - public byte[] getAtqa() { - return delegate.getAtqa(); - } - - @Override - public short getSak() { - return delegate.getSak(); - } - - @Override - public byte[] transceive(byte[] data) throws IOException { - return delegate.transceive(data); - } - - @Override - public int getMaxTransceiveLength() { - return delegate.getMaxTransceiveLength(); - } - - @Override - public void setTimeout(int timeout) { - delegate.setTimeout(timeout); - } - - @Override - public int getTimeout() { - return delegate.getTimeout(); - } - - - @Override - public Tag getTag() { - return new TagWrapper(delegate.getTag()); - } - - @Override - public void connect() throws IOException { - delegate.connect(); - } - - @Override - public void close() throws IOException { - delegate.close(); - } - - @Override - public boolean isConnected() { - return delegate.isConnected(); - } -} - diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcB.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcB.java deleted file mode 100644 index 4f280ea..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcB.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.github.skjolber.android.nfc.tech; - -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagImpl; -import com.github.skjolber.android.nfc.TagWrapper; - -import android.os.Bundle; -import android.os.RemoteException; - -import java.io.IOException; - -/** - * Provides access to NFC-B (ISO 14443-3B) properties and I/O operations on a {@link TagImpl}. - * - *

    Acquire a {@link NfcB} object using {@link #get}. - *

    The primary NFC-B I/O operation is {@link #transceive}. Applications must - * implement their own protocol stack on top of {@link #transceive}. - * - *

    Note: Methods that perform I/O operations - * require the {@link android.Manifest.permission#NFC} permission. - */ -public abstract class NfcB implements BasicTagTechnology { - /** @hide */ - public static final String EXTRA_APPDATA = "appdata"; - /** @hide */ - public static final String EXTRA_PROTINFO = "protinfo"; - - - /** - * Get an instance of {@link NfcBImpl} for the given tag. - *

    Returns null if {@link NfcBImpl} was not enumerated in {@link TagImpl#getTechList}. - * This indicates the tag does not support NFC-B. - *

    Does not cause any RF activity and does not block. - * - * @param tag an NFC-B compatible tag - * @return NFC-B object - */ - - public static NfcB get(Tag tag) { - if(tag instanceof TagImpl) { - TagImpl tagImpl = (TagImpl)tag; - if (!tagImpl.hasTech(TagTechnology.NFC_B)) return null; - try { - return new NfcBImpl(tagImpl); - } catch (RemoteException e) { - return null; - } - } else if(tag instanceof TagWrapper) { - TagWrapper delegate = (TagWrapper)tag; - return new NfcBWrapper(android.nfc.tech.NfcB.get(delegate.getDelegate())); - } else { - throw new IllegalArgumentException(); - } - } - - - /** - * Return the Application Data bytes from ATQB/SENSB_RES at tag discovery. - * - *

    Does not cause any RF activity and does not block. - * - * @return Application Data bytes from ATQB/SENSB_RES bytes - */ - public abstract byte[] getApplicationData(); - - /** - * Return the Protocol Info bytes from ATQB/SENSB_RES at tag discovery. - * - *

    Does not cause any RF activity and does not block. - * - * @return Protocol Info bytes from ATQB/SENSB_RES bytes - */ - public abstract byte[] getProtocolInfo(); - - /** - * Send raw NFC-B commands to the tag and receive the response. - * - *

    Applications must not append the EoD (CRC) to the payload, - * it will be automatically calculated. - *

    Applications must not send commands that manage the polling - * loop and initialization (SENSB_REQ, SLOT_MARKER etc). - * - *

    Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes - * that can be sent with {@link #transceive}. - * - *

    This is an I/O operation and will block until complete. It must - * not be called from the main application thread. A blocked call will be canceled with - * {@link IOException} if {@link #close} is called from another thread. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param data bytes to send - * @return bytes received in response - * @throws android.nfc.TagLostException if the tag leaves the field - * @throws IOException if there is an I/O failure, or this operation is canceled - */ - public abstract byte[] transceive(byte[] data) throws IOException; - - /** - * Return the maximum number of bytes that can be sent with {@link #transceive}. - * @return the maximum number of bytes that can be sent with {@link #transceive}. - */ - public abstract int getMaxTransceiveLength(); -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcBImpl.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcBImpl.java deleted file mode 100644 index d6829bb..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcBImpl.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.github.skjolber.android.nfc.tech; - -import android.os.Bundle; -import android.os.RemoteException; - -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagImpl; - -import java.io.IOException; - -/** - * Provides access to NFC-B (ISO 14443-3B) properties and I/O operations on a {@link TagImpl}. - * - *

    Acquire a {@link NfcBImpl} object using {@link #get}. - *

    The primary NFC-B I/O operation is {@link #transceive}. Applications must - * implement their own protocol stack on top of {@link #transceive}. - * - *

    Note: Methods that perform I/O operations - * require the {@link android.Manifest.permission#NFC} permission. - */ -public final class NfcBImpl extends NfcB { - - private byte[] mAppData; - private byte[] mProtInfo; - - private BasicTagTechnologyImpl delegate; - - public NfcBImpl(TagImpl tag) throws RemoteException { - this.delegate = new BasicTagTechnologyImpl(tag, TagTechnology.NFC_B); - - Bundle extras = tag.getTechExtras(TagTechnology.NFC_B); - mAppData = extras.getByteArray(EXTRA_APPDATA); - mProtInfo = extras.getByteArray(EXTRA_PROTINFO); - } - - /** - * Return the Application Data bytes from ATQB/SENSB_RES at tag discovery. - * - *

    Does not cause any RF activity and does not block. - * - * @return Application Data bytes from ATQB/SENSB_RES bytes - */ - public byte[] getApplicationData() { - return mAppData; - } - - /** - * Return the Protocol Info bytes from ATQB/SENSB_RES at tag discovery. - * - *

    Does not cause any RF activity and does not block. - * - * @return Protocol Info bytes from ATQB/SENSB_RES bytes - */ - public byte[] getProtocolInfo() { - return mProtInfo; - } - - /** - * Send raw NFC-B commands to the tag and receive the response. - * - *

    Applications must not append the EoD (CRC) to the payload, - * it will be automatically calculated. - *

    Applications must not send commands that manage the polling - * loop and initialization (SENSB_REQ, SLOT_MARKER etc). - * - *

    Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes - * that can be sent with {@link #transceive}. - * - *

    This is an I/O operation and will block until complete. It must - * not be called from the main application thread. A blocked call will be canceled with - * {@link IOException} if {@link #close} is called from another thread. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param data bytes to send - * @return bytes received in response - * @throws android.nfc.TagLostException if the tag leaves the field - * @throws IOException if there is an I/O failure, or this operation is canceled - */ - public byte[] transceive(byte[] data) throws IOException { - return delegate.transceive(data, true); - } - - /** - * Return the maximum number of bytes that can be sent with {@link #transceive}. - * @return the maximum number of bytes that can be sent with {@link #transceive}. - */ - public int getMaxTransceiveLength() { - return delegate.getMaxTransceiveLengthInternal(); - } - - - @Override - public Tag getTag() { - return delegate.getTag(); - } - - @Override - public void connect() throws IOException { - delegate.connect(); - } - - @Override - public void close() throws IOException { - delegate.close(); - } - - @Override - public boolean isConnected() { - return delegate.isConnected(); - } -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcBWrapper.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcBWrapper.java deleted file mode 100644 index 954cdbe..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcBWrapper.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.github.skjolber.android.nfc.tech; - -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagWrapper; - -import java.io.IOException; - -public class NfcBWrapper extends NfcB { - - protected android.nfc.tech.NfcB delegate; - - public NfcBWrapper(android.nfc.tech.NfcB delegate) { - this.delegate = delegate; - } - - @Override - public byte[] getApplicationData() { - return delegate.getApplicationData(); - } - - @Override - public byte[] getProtocolInfo() { - return delegate.getProtocolInfo(); - } - - @Override - public byte[] transceive(byte[] data) throws IOException { - return delegate.transceive(data); - } - - @Override - public int getMaxTransceiveLength() { - return delegate.getMaxTransceiveLength(); - } - - @Override - public Tag getTag() { - return new TagWrapper(delegate.getTag()); - } - - @Override - public void connect() throws IOException { - delegate.connect(); - } - - @Override - public void close() throws IOException { - delegate.close(); - } - - @Override - public boolean isConnected() { - return delegate.isConnected(); - } - -} - diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcBarcode.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcBarcode.java deleted file mode 100644 index 1815d0e..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcBarcode.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.github.skjolber.android.nfc.tech; - -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagImpl; -import com.github.skjolber.android.nfc.TagWrapper; - -import android.os.Bundle; -import android.os.RemoteException; - -/** - * Provides access to tags containing just a barcode. - * - *

    Acquire an {@link NfcBarcode} object using {@link #get}. - * - */ -public abstract class NfcBarcode implements BasicTagTechnology { - - /** Kovio Tags */ - public static final int TYPE_KOVIO = 1; - public static final int TYPE_UNKNOWN = -1; - - /** @hide */ - public static final String EXTRA_BARCODE_TYPE = "barcodetype"; - - /** - * Get an instance of {@link NfcBarcode} for the given tag. - * - *

    Returns null if {@link NfcBarcode} was not enumerated in {@link TagImpl#getTechList}. - * - *

    Does not cause any RF activity and does not block. - * - * @param tag an NfcBarcode compatible tag - * @return NfcBarcode object - */ - public static NfcBarcode get(Tag tag) { - if(tag instanceof TagImpl) { - TagImpl tagImpl = (TagImpl)tag; - if (!tagImpl.hasTech(TagTechnology.NFC_BARCODE)) return null; - try { - return new NfcBarcodeImpl(tagImpl); - } catch (RemoteException e) { - return null; - } - } else if(tag instanceof TagWrapper) { - TagWrapper delegate = (TagWrapper)tag; - return new NfcBarcodeWrapper(android.nfc.tech.NfcBarcode.get(delegate.getDelegate())); - } else { - throw new IllegalArgumentException(); - } - } - - /** - * Returns the NFC Barcode tag type. - * - *

    Currently only one of {@link #TYPE_KOVIO} or {@link #TYPE_UNKNOWN}. - * - *

    Does not cause any RF activity and does not block. - * - * @return the NFC Barcode tag type - */ - public abstract int getType(); - - /** - * Returns the barcode of an NfcBarcode tag. - * - *

    Tags of {@link #TYPE_KOVIO} return 16 bytes: - *

      - *

      The first byte is 0x80 ORd with a manufacturer ID, corresponding - * to ISO/IEC 7816-6. - *

      The second byte describes the payload data format. Defined data - * format types include the following:

        - *
      • 0x00: Reserved for manufacturer assignment
      • - *
      • 0x01: 96-bit URL with "http://www." prefix
      • - *
      • 0x02: 96-bit URL with "https://www." prefix
      • - *
      • 0x03: 96-bit URL with "http://" prefix
      • - *
      • 0x04: 96-bit URL with "https://" prefix
      • - *
      • 0x05: 96-bit GS1 EPC
      • - *
      • 0x06-0xFF: reserved
      • - *
      - *

      The following 12 bytes are payload:

      - *

      The last 2 bytes comprise the CRC. - *

    - *

    Does not cause any RF activity and does not block. - * - * @return a byte array containing the barcode - * @see - * Thinfilm NFC Barcode tag specification (previously Kovio NFC Barcode) - * @see - * Thinfilm NFC Barcode data format (previously Kovio NFC Barcode) - */ - public abstract byte[] getBarcode(); -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcBarcodeImpl.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcBarcodeImpl.java deleted file mode 100644 index 46809c1..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcBarcodeImpl.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.github.skjolber.android.nfc.tech; - -import android.os.Bundle; -import android.os.RemoteException; - -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagImpl; - -import java.io.IOException; - -/** - * Provides access to tags containing just a barcode. - * - *

    Acquire an {@link NfcBarcodeImpl} object using {@link #get}. - * - */ -public final class NfcBarcodeImpl extends NfcBarcode { - - /** Kovio Tags */ - public static final int TYPE_KOVIO = 1; - public static final int TYPE_UNKNOWN = -1; - - /** @hide */ - public static final String EXTRA_BARCODE_TYPE = "barcodetype"; - - private int mType; - - /** - * Internal constructor, to be used by NfcAdapter - */ - - private BasicTagTechnologyImpl delegate; - - public NfcBarcodeImpl(TagImpl tag) throws RemoteException { - this.delegate = new BasicTagTechnologyImpl(tag, TagTechnology.NFC_BARCODE); - - Bundle extras = tag.getTechExtras(TagTechnology.NFC_BARCODE); - if (extras != null) { - mType = extras.getInt(EXTRA_BARCODE_TYPE); - } else { - throw new NullPointerException("NfcBarcode tech extras are null."); - } - } - - /** - * Returns the NFC Barcode tag type. - * - *

    Currently only one of {@link #TYPE_KOVIO} or {@link #TYPE_UNKNOWN}. - * - *

    Does not cause any RF activity and does not block. - * - * @return the NFC Barcode tag type - */ - public int getType() { - return mType; - } - - /** - * Returns the barcode of an NfcBarcode tag. - * - *

    Tags of {@link #TYPE_KOVIO} return 16 bytes: - *

      - *

      The first byte is 0x80 ORd with a manufacturer ID, corresponding - * to ISO/IEC 7816-6. - *

      The second byte describes the payload data format. Defined data - * format types include the following:

        - *
      • 0x00: Reserved for manufacturer assignment
      • - *
      • 0x01: 96-bit URL with "http://www." prefix
      • - *
      • 0x02: 96-bit URL with "https://www." prefix
      • - *
      • 0x03: 96-bit URL with "http://" prefix
      • - *
      • 0x04: 96-bit URL with "https://" prefix
      • - *
      • 0x05: 96-bit GS1 EPC
      • - *
      • 0x06-0xFF: reserved
      • - *
      - *

      The following 12 bytes are payload:

      - *

      The last 2 bytes comprise the CRC. - *

    - *

    Does not cause any RF activity and does not block. - * - * @return a byte array containing the barcode - * @see - * Thinfilm NFC Barcode tag specification (previously Kovio NFC Barcode) - * @see - * Thinfilm NFC Barcode data format (previously Kovio NFC Barcode) - */ - public byte[] getBarcode() { - switch (mType) { - case TYPE_KOVIO: - // For Kovio tags the barcode matches the ID - return delegate.getTag().getId(); - default: - return null; - } - } - - - @Override - public Tag getTag() { - return delegate.getTag(); - } - - @Override - public void connect() throws IOException { - delegate.connect(); - } - - @Override - public void close() throws IOException { - delegate.close(); - } - - @Override - public boolean isConnected() { - return delegate.isConnected(); - } -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcBarcodeWrapper.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcBarcodeWrapper.java deleted file mode 100644 index 7b7c343..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcBarcodeWrapper.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.github.skjolber.android.nfc.tech; - -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagWrapper; - -import java.io.IOException; - -public class NfcBarcodeWrapper extends NfcBarcode { - - protected android.nfc.tech.NfcBarcode delegate; - - public NfcBarcodeWrapper(android.nfc.tech.NfcBarcode delegate) { - this.delegate = delegate; - } - - @Override - public Tag getTag() { - return new TagWrapper(delegate.getTag()); - } - - @Override - public void connect() throws IOException { - delegate.connect(); - } - - @Override - public void close() throws IOException { - delegate.close(); - } - - @Override - public boolean isConnected() { - return delegate.isConnected(); - } - - @Override - public int getType() { - return delegate.getType(); - } - - @Override - public byte[] getBarcode() { - return delegate.getBarcode(); - } -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcF.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcF.java deleted file mode 100644 index ff5698d..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcF.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.github.skjolber.android.nfc.tech; - -import com.github.skjolber.android.nfc.ErrorCodes; -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagImpl; -import com.github.skjolber.android.nfc.TagWrapper; - -import android.os.Bundle; -import android.os.RemoteException; -import android.util.Log; - -import java.io.IOException; - -/** - * Provides access to NFC-F (JIS 6319-4) properties and I/O operations on a {@link TagImpl}. - * - *

    Acquire a {@link NfcF} object using {@link #get}. - *

    The primary NFC-F I/O operation is {@link #transceive}. Applications must - * implement their own protocol stack on top of {@link #transceive}. - * - *

    Note: Methods that perform I/O operations - * require the {@link android.Manifest.permission#NFC} permission. - */ -public abstract class NfcF implements BasicTagTechnology { - - /** @hide */ - public static final String EXTRA_SC = "systemcode"; - /** @hide */ - public static final String EXTRA_PMM = "pmm"; - - /** - * Get an instance of {@link NfcF} for the given tag. - *

    Returns null if {@link NfcF} was not enumerated in {@link TagImpl#getTechList}. - * This indicates the tag does not support NFC-F. - *

    Does not cause any RF activity and does not block. - * - * @param tag an NFC-F compatible tag - * @return NFC-F object - */ - public static NfcF get(Tag tag) { - if(tag instanceof TagImpl) { - TagImpl tagImpl = (TagImpl)tag; - if (!tagImpl.hasTech(TagTechnology.NFC_F)) return null; - try { - return new NfcFImpl(tagImpl); - } catch (RemoteException e) { - return null; - } - } else if(tag instanceof TagWrapper) { - TagWrapper delegate = (TagWrapper)tag; - return new NfcFWrapper(android.nfc.tech.NfcF.get(delegate.getDelegate())); - } else { - throw new IllegalArgumentException(); - } - - } - - /** - * Return the System Code bytes from tag discovery. - * - *

    Does not cause any RF activity and does not block. - * - * @return System Code bytes - */ - public abstract byte[] getSystemCode(); - - /** - * Return the Manufacturer bytes from tag discovery. - * - *

    Does not cause any RF activity and does not block. - * - * @return Manufacturer bytes - */ - public abstract byte[] getManufacturer(); - - /** - * Send raw NFC-F commands to the tag and receive the response. - * - *

    Applications must not prefix the SoD (preamble and sync code) - * and/or append the EoD (CRC) to the payload, it will be automatically calculated. - * - *

    A typical NFC-F frame for this method looks like: - *

    -     * LENGTH (1 byte) --- CMD (1 byte) -- IDm (8 bytes) -- PARAMS (LENGTH - 10 bytes)
    -     * 
    - * - *

    Use {@link #getMaxTransceiveLength} to retrieve the maximum amount of bytes - * that can be sent with {@link #transceive}. - * - *

    This is an I/O operation and will block until complete. It must - * not be called from the main application thread. A blocked call will be canceled with - * {@link IOException} if {@link #close} is called from another thread. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param data bytes to send - * @return bytes received in response - * @throws android.nfc.TagLostException if the tag leaves the field - * @throws IOException if there is an I/O failure, or this operation is canceled - */ - public abstract byte[] transceive(byte[] data) throws IOException; - - /** - * Return the maximum number of bytes that can be sent with {@link #transceive}. - * @return the maximum number of bytes that can be sent with {@link #transceive}. - */ - public abstract int getMaxTransceiveLength(); - - /** - * Set the {@link #transceive} timeout in milliseconds. - * - *

    The timeout only applies to {@link #transceive} on this object, - * and is reset to a default value when {@link #close} is called. - * - *

    Setting a longer timeout may be useful when performing - * transactions that require a long processing time on the tag - * such as key generation. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param timeout timeout value in milliseconds - */ - public abstract void setTimeout(int timeout); - - /** - * Get the current {@link #transceive} timeout in milliseconds. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @return timeout value in milliseconds - */ - public abstract int getTimeout(); -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcFImpl.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcFImpl.java deleted file mode 100644 index 1b00081..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcFImpl.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.github.skjolber.android.nfc.tech; - -import android.os.Bundle; -import android.os.RemoteException; -import android.util.Log; - -import com.github.skjolber.android.nfc.ErrorCodes; -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagImpl; - -import java.io.IOException; - -/** - * Provides access to NFC-F (JIS 6319-4) properties and I/O operations on a {@link TagImpl}. - * - *

    Acquire a {@link NfcFImpl} object using {@link #get}. - *

    The primary NFC-F I/O operation is {@link #transceive}. Applications must - * implement their own protocol stack on top of {@link #transceive}. - * - *

    Note: Methods that perform I/O operations - * require the {@link android.Manifest.permission#NFC} permission. - */ -public final class NfcFImpl extends NfcF { - private static final String TAG = "NFC"; - - /** @hide */ - public static final String EXTRA_SC = "systemcode"; - /** @hide */ - public static final String EXTRA_PMM = "pmm"; - - private byte[] mSystemCode = null; - private byte[] mManufacturer = null; - - private BasicTagTechnologyImpl delegate; - - public NfcFImpl(TagImpl tag) throws RemoteException { - this.delegate = new BasicTagTechnologyImpl(tag, TagTechnology.NFC_F); - - Bundle extras = tag.getTechExtras(TagTechnology.NFC_F); - if (extras != null) { - mSystemCode = extras.getByteArray(EXTRA_SC); - mManufacturer = extras.getByteArray(EXTRA_PMM); - } - } - - /** - * Return the System Code bytes from tag discovery. - * - *

    Does not cause any RF activity and does not block. - * - * @return System Code bytes - */ - public byte[] getSystemCode() { - return mSystemCode; - } - - /** - * Return the Manufacturer bytes from tag discovery. - * - *

    Does not cause any RF activity and does not block. - * - * @return Manufacturer bytes - */ - public byte[] getManufacturer() { - return mManufacturer; - } - - /** - * Send raw NFC-F commands to the tag and receive the response. - * - *

    Applications must not prefix the SoD (preamble and sync code) - * and/or append the EoD (CRC) to the payload, it will be automatically calculated. - * - *

    A typical NFC-F frame for this method looks like: - *

    -     * LENGTH (1 byte) --- CMD (1 byte) -- IDm (8 bytes) -- PARAMS (LENGTH - 10 bytes)
    -     * 
    - * - *

    Use {@link #getMaxTransceiveLength} to retrieve the maximum amount of bytes - * that can be sent with {@link #transceive}. - * - *

    This is an I/O operation and will block until complete. It must - * not be called from the main application thread. A blocked call will be canceled with - * {@link IOException} if {@link #close} is called from another thread. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param data bytes to send - * @return bytes received in response - * @throws android.nfc.TagLostException if the tag leaves the field - * @throws IOException if there is an I/O failure, or this operation is canceled - */ - public byte[] transceive(byte[] data) throws IOException { - return delegate.transceive(data, true); - } - - /** - * Return the maximum number of bytes that can be sent with {@link #transceive}. - * @return the maximum number of bytes that can be sent with {@link #transceive}. - */ - public int getMaxTransceiveLength() { - return delegate.getMaxTransceiveLengthInternal(); - } - - /** - * Set the {@link #transceive} timeout in milliseconds. - * - *

    The timeout only applies to {@link #transceive} on this object, - * and is reset to a default value when {@link #close} is called. - * - *

    Setting a longer timeout may be useful when performing - * transactions that require a long processing time on the tag - * such as key generation. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param timeout timeout value in milliseconds - */ - public void setTimeout(int timeout) { - try { - int err = delegate.getTag().getTagService().setTimeout(TagTechnology.NFC_F, timeout); - if (err != ErrorCodes.SUCCESS) { - throw new IllegalArgumentException("The supplied timeout is not valid"); - } - } catch (RemoteException e) { - Log.e(TAG, "NFC service dead", e); - } - } - - /** - * Get the current {@link #transceive} timeout in milliseconds. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @return timeout value in milliseconds - */ - public int getTimeout() { - try { - return delegate.getTag().getTagService().getTimeout(TagTechnology.NFC_F); - } catch (RemoteException e) { - Log.e(TAG, "NFC service dead", e); - return 0; - } - } - - - @Override - public Tag getTag() { - return delegate.getTag(); - } - - @Override - public void connect() throws IOException { - delegate.connect(); - } - - @Override - public void close() throws IOException { - delegate.close(); - } - - @Override - public boolean isConnected() { - return delegate.isConnected(); - } - -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcFWrapper.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcFWrapper.java deleted file mode 100644 index 35e5e38..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcFWrapper.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.github.skjolber.android.nfc.tech; - -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagWrapper; - -import java.io.IOException; - -public class NfcFWrapper extends NfcF { - - protected android.nfc.tech.NfcF delegate; - - public NfcFWrapper(android.nfc.tech.NfcF delegate) { - this.delegate = delegate; - } - - - @Override - public byte[] getSystemCode() { - return delegate.getSystemCode(); - } - - @Override - public byte[] getManufacturer() { - return delegate.getManufacturer(); - } - - @Override - public byte[] transceive(byte[] data) throws IOException { - return delegate.transceive(data); - } - - @Override - public int getMaxTransceiveLength() { - return delegate.getMaxTransceiveLength(); - } - - @Override - public void setTimeout(int timeout) { - delegate.setTimeout(timeout); - } - - @Override - public int getTimeout() { - return delegate.getTimeout(); - } - - @Override - public Tag getTag() { - return new TagWrapper(delegate.getTag()); - } - - @Override - public void connect() throws IOException { - delegate.connect(); - } - - @Override - public void close() throws IOException { - delegate.close(); - } - - @Override - public boolean isConnected() { - return delegate.isConnected(); - } - -} - diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcV.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcV.java deleted file mode 100644 index e883b68..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcV.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.github.skjolber.android.nfc.tech; - -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagImpl; -import com.github.skjolber.android.nfc.TagWrapper; - -import android.os.Bundle; -import android.os.RemoteException; - -import java.io.IOException; - -/** - * Provides access to NFC-V (ISO 15693) properties and I/O operations on a {@link TagImpl}. - * - *

    Acquire a {@link NfcV} object using {@link #get}. - *

    The primary NFC-V I/O operation is {@link #transceive}. Applications must - * implement their own protocol stack on top of {@link #transceive}. - * - *

    Note: Methods that perform I/O operations - * require the {@link android.Manifest.permission#NFC} permission. - */ -public abstract class NfcV implements BasicTagTechnology { - /** @hide */ - public static final String EXTRA_RESP_FLAGS = "respflags"; - - /** @hide */ - public static final String EXTRA_DSFID = "dsfid"; - - private byte mRespFlags; - private byte mDsfId; - - /** - * Get an instance of {@link NfcV} for the given tag. - *

    Returns null if {@link NfcV} was not enumerated in {@link TagImpl#getTechList}. - * This indicates the tag does not support NFC-V. - *

    Does not cause any RF activity and does not block. - * - * @param tag an NFC-V compatible tag - * @return NFC-V object - */ - public static NfcV get(Tag tag) { - if(tag instanceof TagImpl) { - TagImpl tagImpl = (TagImpl)tag; - if (!tagImpl.hasTech(TagTechnology.NFC_V)) return null; - try { - return new NfcVImpl(tagImpl); - } catch (RemoteException e) { - return null; - } - } else if(tag instanceof TagWrapper) { - TagWrapper delegate = (TagWrapper)tag; - return new NfcVWrapper(android.nfc.tech.NfcV.get(delegate.getDelegate())); - } else { - throw new IllegalArgumentException(); - } - } - - /** - * Return the Response Flag bytes from tag discovery. - * - *

    Does not cause any RF activity and does not block. - * - * @return Response Flag bytes - */ - public byte getResponseFlags() { - return mRespFlags; - } - - /** - * Return the DSF ID bytes from tag discovery. - * - *

    Does not cause any RF activity and does not block. - * - * @return DSF ID bytes - */ - public byte getDsfId() { - return mDsfId; - } - - /** - * Send raw NFC-V commands to the tag and receive the response. - * - *

    Applications must not append the CRC to the payload, - * it will be automatically calculated. The application does - * provide FLAGS, CMD and PARAMETER bytes. - * - *

    Use {@link #getMaxTransceiveLength} to retrieve the maximum amount of bytes - * that can be sent with {@link #transceive}. - * - *

    This is an I/O operation and will block until complete. It must - * not be called from the main application thread. A blocked call will be canceled with - * {@link IOException} if {@link #close} is called from another thread. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param data bytes to send - * @return bytes received in response - * @throws android.nfc.TagLostException if the tag leaves the field - * @throws IOException if there is an I/O failure, or this operation is canceled - */ - public abstract byte[] transceive(byte[] data) throws IOException; - - - /** - * Return the maximum number of bytes that can be sent with {@link #transceive}. - * @return the maximum number of bytes that can be sent with {@link #transceive}. - */ - public abstract int getMaxTransceiveLength(); -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcVImpl.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcVImpl.java deleted file mode 100644 index 77e5605..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcVImpl.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.github.skjolber.android.nfc.tech; - -import android.os.Bundle; -import android.os.RemoteException; - -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagImpl; - -import java.io.IOException; - -/** - * Provides access to NFC-V (ISO 15693) properties and I/O operations on a {@link TagImpl}. - * - *

    Acquire a {@link NfcVImpl} object using {@link #get}. - *

    The primary NFC-V I/O operation is {@link #transceive}. Applications must - * implement their own protocol stack on top of {@link #transceive}. - * - *

    Note: Methods that perform I/O operations - * require the {@link android.Manifest.permission#NFC} permission. - */ -public class NfcVImpl extends NfcV { - public static final String EXTRA_RESP_FLAGS = "respflags"; - - /** @hide */ - public static final String EXTRA_DSFID = "dsfid"; - - private byte mRespFlags; - private byte mDsfId; - - private BasicTagTechnologyImpl delegate; - - public NfcVImpl(TagImpl tag) throws RemoteException { - this.delegate = new BasicTagTechnologyImpl(tag, TagTechnology.NFC_V); - - Bundle extras = tag.getTechExtras(TagTechnology.NFC_V); - mRespFlags = extras.getByte(EXTRA_RESP_FLAGS); - mDsfId = extras.getByte(EXTRA_DSFID); - } - - /** - * Return the Response Flag bytes from tag discovery. - * - *

    Does not cause any RF activity and does not block. - * - * @return Response Flag bytes - */ - public byte getResponseFlags() { - return mRespFlags; - } - - /** - * Return the DSF ID bytes from tag discovery. - * - *

    Does not cause any RF activity and does not block. - * - * @return DSF ID bytes - */ - public byte getDsfId() { - return mDsfId; - } - - /** - * Send raw NFC-V commands to the tag and receive the response. - * - *

    Applications must not append the CRC to the payload, - * it will be automatically calculated. The application does - * provide FLAGS, CMD and PARAMETER bytes. - * - *

    Use {@link #getMaxTransceiveLength} to retrieve the maximum amount of bytes - * that can be sent with {@link #transceive}. - * - *

    This is an I/O operation and will block until complete. It must - * not be called from the main application thread. A blocked call will be canceled with - * {@link IOException} if {@link #close} is called from another thread. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @param data bytes to send - * @return bytes received in response - * @throws android.nfc.TagLostException if the tag leaves the field - * @throws IOException if there is an I/O failure, or this operation is canceled - */ - public byte[] transceive(byte[] data) throws IOException { - return delegate.transceive(data, true); - } - - - /** - * Return the maximum number of bytes that can be sent with {@link #transceive}. - * @return the maximum number of bytes that can be sent with {@link #transceive}. - */ - public int getMaxTransceiveLength() { - return delegate.getMaxTransceiveLengthInternal(); - } - - @Override - public Tag getTag() { - return delegate.getTag(); - } - - @Override - public void connect() throws IOException { - delegate.connect(); - } - - @Override - public void close() throws IOException { - delegate.close(); - } - - @Override - public boolean isConnected() { - return delegate.isConnected(); - } -} diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcVWrapper.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcVWrapper.java deleted file mode 100644 index 1154325..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/NfcVWrapper.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.github.skjolber.android.nfc.tech; - -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagWrapper; - -import java.io.IOException; - -public class NfcVWrapper extends NfcV { - - protected android.nfc.tech.NfcV delegate; - - public NfcVWrapper(android.nfc.tech.NfcV delegate) { - this.delegate = delegate; - } - - @Override - public byte[] transceive(byte[] data) throws IOException { - return delegate.transceive(data); - } - - @Override - public int getMaxTransceiveLength() { - return delegate.getMaxTransceiveLength(); - } - - @Override - public Tag getTag() { - return new TagWrapper(delegate.getTag()); - } - - @Override - public void connect() throws IOException { - delegate.connect(); - } - - @Override - public void close() throws IOException { - delegate.close(); - } - - @Override - public boolean isConnected() { - return delegate.isConnected(); - } - -} - diff --git a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/TagTechnology.java b/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/TagTechnology.java deleted file mode 100644 index 6d67d58..0000000 --- a/wrapper/src/main/java/com/github/skjolber/android/nfc/tech/TagTechnology.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.github.skjolber.android.nfc.tech; - -import com.github.skjolber.android.nfc.Tag; -import com.github.skjolber.android.nfc.TagImpl; - -import java.io.Closeable; -import java.io.IOException; - -/** - * {@link TagTechnology} is an interface to a technology in a {@link TagImpl}. - *

    - * Obtain a {@link TagTechnology} implementation by calling the static method get() - * on the implementation class. - *

    - * NFC tags are based on a number of independently developed technologies and offer a - * wide range of capabilities. The - * {@link TagTechnology} implementations provide access to these different - * technologies and capabilities. Some sub-classes map to technology - * specification (for example {@link NfcAImpl}, {@link IsoDepImpl}, others map to - * pseudo-technologies or capabilities (for example {@link NdefImpl}, {@link NdefFormatable}). - *

    - * It is mandatory for all Android NFC devices to provide the following - * {@link TagTechnology} implementations. - *

      - *
    • {@link NfcAImpl} (also known as ISO 14443-3A) - *
    • {@link NfcB} (also known as ISO 14443-3B) - *
    • {@link NfcF} (also known as JIS 6319-4) - *
    • {@link NfcV} (also known as ISO 15693) - *
    • {@link IsoDepImpl} - *
    • {@link NdefImpl} on NFC Forum Type 1, Type 2, Type 3 or Type 4 compliant tags - *
    - * It is optional for Android NFC devices to provide the following - * {@link TagTechnology} implementations. If it is not provided, the - * Android device will never enumerate that class via {@link TagImpl#getTechList}. - *
      - *
    • {@link MifareClassicImpl} - *
    • {@link MifareUltralightImpl} - *
    • {@link NfcBarcode} - *
    • {@link NdefFormatable} must only be enumerated on tags for which this Android device - * is capable of formatting. Proprietary knowledge is often required to format a tag - * to make it NDEF compatible. - *
    - *

    - * {@link TagTechnology} implementations provide methods that fall into two classes: - * cached getters and I/O operations. - *

    Cached getters

    - * These methods (usually prefixed by get or is) return - * properties of the tag, as determined at discovery time. These methods will never - * block or cause RF activity, and do not require {@link #connect} to have been called. - * They also never update, for example if a property is changed by an I/O operation with a tag - * then the cached getter will still return the result from tag discovery time. - *

    I/O operations

    - * I/O operations may require RF activity, and may block. They have the following semantics. - *
      - *
    • {@link #connect} must be called before using any other I/O operation. - *
    • {@link #close} must be called after completing I/O operations with a - * {@link TagTechnology}, and it will cancel all other blocked I/O operations on other threads - * (including {@link #connect} with {@link IOException}. - *
    • Only one {@link TagTechnology} can be connected at a time. Other calls to - * {@link #connect} will return {@link IOException}. - *
    • I/O operations may block, and should never be called on the main application - * thread. - *
    - * - *

    Note: Methods that perform I/O operations - * require the {@link android.Manifest.permission#NFC} permission. - */ -public interface TagTechnology extends Closeable { - /** - * This technology is an instance of {@link NfcAImpl}. - *

    Support for this technology type is mandatory. - * @hide - */ - public static final int NFC_A = 1; - - /** - * This technology is an instance of {@link NfcB}. - *

    Support for this technology type is mandatory. - * @hide - */ - public static final int NFC_B = 2; - - /** - * This technology is an instance of {@link IsoDepImpl}. - *

    Support for this technology type is mandatory. - * @hide - */ - public static final int ISO_DEP = 3; - - /** - * This technology is an instance of {@link NfcF}. - *

    Support for this technology type is mandatory. - * @hide - */ - public static final int NFC_F = 4; - - /** - * This technology is an instance of {@link NfcV}. - *

    Support for this technology type is mandatory. - * @hide - */ - public static final int NFC_V = 5; - - /** - * This technology is an instance of {@link NdefImpl}. - *

    Support for this technology type is mandatory. - * @hide - */ - public static final int NDEF = 6; - - /** - * This technology is an instance of {@link NdefFormatable}. - *

    Support for this technology type is mandatory. - * @hide - */ - public static final int NDEF_FORMATABLE = 7; - - /** - * This technology is an instance of {@link MifareClassicImpl}. - *

    Support for this technology type is optional. If a stack doesn't support this technology - * type tags using it must still be discovered and present the lower level radio interface - * technologies in use. - * @hide - */ - public static final int MIFARE_CLASSIC = 8; - - /** - * This technology is an instance of {@link MifareUltralightImpl}. - *

    Support for this technology type is optional. If a stack doesn't support this technology - * type tags using it must still be discovered and present the lower level radio interface - * technologies in use. - * @hide - */ - public static final int MIFARE_ULTRALIGHT = 9; - - /** - * This technology is an instance of {@link NfcBarcode}. - *

    Support for this technology type is optional. If a stack doesn't support this technology - * type tags using it must still be discovered and present the lower level radio interface - * technologies in use. - * @hide - */ - public static final int NFC_BARCODE = 10; - - /** - * Get the {@link TagImpl} object backing this {@link TagTechnology} object. - * @return the {@link TagImpl} backing this {@link TagTechnology} object. - */ - public Tag getTag(); - - /** - * Enable I/O operations to the tag from this {@link TagTechnology} object. - *

    May cause RF activity and may block. Must not be called - * from the main application thread. A blocked call will be canceled with - * {@link IOException} by calling {@link #close} from another thread. - *

    Only one {@link TagTechnology} object can be connected to a {@link TagImpl} at a time. - *

    Applications must call {@link #close} when I/O operations are complete. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @see #close() - * @throws android.nfc.TagLostException if the tag leaves the field - * @throws IOException if there is an I/O failure, or connect is canceled - */ - public void connect() throws IOException; - - /** - * Disable I/O operations to the tag from this {@link TagTechnology} object, and release resources. - *

    Also causes all blocked I/O operations on other thread to be canceled and - * return with {@link IOException}. - * - *

    Requires the {@link android.Manifest.permission#NFC} permission. - * - * @see #connect() - */ - public void close() throws IOException; - - /** - * Helper to indicate if I/O operations should be possible. - * - *

    Returns true if {@link #connect} has completed, and {@link #close} has not been - * called, and the {@link TagImpl} is not known to be out of range. - *

    Does not cause RF activity, and does not block. - * - * @return true if I/O operations should be possible - */ - public boolean isConnected(); -}