Merge "Merge branch gingerbread-nfc into gingerbread." into gingerbread
This commit is contained in:
@@ -119,11 +119,11 @@ LOCAL_SRC_FILES += \
|
||||
core/java/android/nfc/ILlcpConnectionlessSocket.aidl \
|
||||
core/java/android/nfc/ILlcpServiceSocket.aidl \
|
||||
core/java/android/nfc/ILlcpSocket.aidl \
|
||||
core/java/android/nfc/INdefTag.aidl \
|
||||
core/java/android/nfc/INfcAdapter.aidl \
|
||||
core/java/android/nfc/INfcTag.aidl \
|
||||
core/java/android/nfc/IP2pInitiator.aidl \
|
||||
core/java/android/nfc/IP2pTarget.aidl \
|
||||
core/java/android/nfc/INfcSecureElement.aidl \
|
||||
core/java/android/os/IHardwareService.aidl \
|
||||
core/java/android/os/IMessenger.aidl \
|
||||
core/java/android/os/INetworkManagementService.aidl \
|
||||
@@ -252,7 +252,6 @@ aidl_files := \
|
||||
frameworks/base/core/java/android/nfc/NdefMessage.aidl \
|
||||
frameworks/base/core/java/android/nfc/NdefRecord.aidl \
|
||||
frameworks/base/core/java/android/nfc/Tag.aidl \
|
||||
frameworks/base/core/java/android/nfc/NdefTag.aidl \
|
||||
frameworks/base/core/java/android/os/Bundle.aidl \
|
||||
frameworks/base/core/java/android/os/DropBoxManager.aidl \
|
||||
frameworks/base/core/java/android/os/ParcelFileDescriptor.aidl \
|
||||
|
||||
@@ -72,6 +72,7 @@ $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framew
|
||||
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/src/com/trustedlogic)
|
||||
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/com/trustedlogic)
|
||||
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/src/com/trustedlogic)
|
||||
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/nfc/INdefTag.java)
|
||||
|
||||
# ************************************************
|
||||
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.nfc.ILlcpConnectionlessSocket;
|
||||
import android.nfc.INfcTag;
|
||||
import android.nfc.IP2pTarget;
|
||||
import android.nfc.IP2pInitiator;
|
||||
import android.nfc.INfcSecureElement;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
@@ -36,9 +37,12 @@ interface INfcAdapter
|
||||
INfcTag getNfcTagInterface();
|
||||
IP2pTarget getP2pTargetInterface();
|
||||
IP2pInitiator getP2pInitiatorInterface();
|
||||
INfcSecureElement getNfcSecureElementInterface();
|
||||
|
||||
// NfcAdapter-class related methods
|
||||
boolean isEnabled();
|
||||
NdefMessage localGet();
|
||||
void localSet(in NdefMessage message);
|
||||
void openTagConnection(in Tag tag);
|
||||
|
||||
// Non-public methods
|
||||
|
||||
14
core/java/android/nfc/INdefTag.aidl → core/java/android/nfc/INfcSecureElement.aidl
Normal file → Executable file
14
core/java/android/nfc/INdefTag.aidl → core/java/android/nfc/INfcSecureElement.aidl
Normal file → Executable file
@@ -16,13 +16,13 @@
|
||||
|
||||
package android.nfc;
|
||||
|
||||
import android.nfc.NdefMessage;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
* {@hide}
|
||||
*/
|
||||
interface INdefTag
|
||||
{
|
||||
NdefMessage read(int nativeHandle);
|
||||
boolean write(int nativeHandle, in NdefMessage msg);
|
||||
interface INfcSecureElement {
|
||||
int openSecureElementConnection();
|
||||
int closeSecureElementConnection(int nativeHandle);
|
||||
byte[] exchangeAPDU(int nativeHandle, in byte[] data);
|
||||
int[] getSecureElementTechList(int nativeHandle);
|
||||
byte[] getSecureElementUid(int nativeHandle);
|
||||
}
|
||||
@@ -25,7 +25,7 @@ interface INfcTag
|
||||
{
|
||||
int close(int nativeHandle);
|
||||
int connect(int nativeHandle);
|
||||
String getType(int nativeHandle);
|
||||
int[] getTechList(int nativeHandle);
|
||||
byte[] getUid(int nativeHandle);
|
||||
boolean isNdef(int nativeHandle);
|
||||
boolean isPresent(int nativeHandle);
|
||||
|
||||
@@ -1,19 +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 android.nfc;
|
||||
|
||||
parcelable NdefTag;
|
||||
@@ -1,245 +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 android.nfc;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
/**
|
||||
* Represents a discovered tag that contains {@link NdefMessage}s (or a tag that can store them).
|
||||
* In practice, a tag is a thing that an NFC-enabled device can communicate with. This
|
||||
* class is a representation of such a tag and can contain the NDEF messages shared by the tag.
|
||||
* <p>An NDEF tag can contain zero or more NDEF messages (represented by {@link NdefMessage}
|
||||
* objects) in addition to the basic tag properties of UID and Type.
|
||||
* <p>
|
||||
* {@link NdefTag}s that have been initialized will usually contain a single {@link NdefMessage}
|
||||
* (and that Message can contain multiple {@link NdefRecord}s). However it
|
||||
* is possible for {@link NdefTag}s to contain multiple {@link NdefMessage}s.
|
||||
* <p>{@link NfcAdapter#createNdefTagConnection createNdefTagConnection()} can be used to modify the
|
||||
* contents of some tags.
|
||||
* <p>This is an immutable data class. All properties are set at Tag discovery
|
||||
* time and calls on this class will retrieve those read-only properties, and
|
||||
* not cause any further RF activity or block. Note however that arrays passed to and
|
||||
* returned by this class are *not* cloned, so be careful not to modify them.
|
||||
* @hide
|
||||
*/
|
||||
public class NdefTag extends Tag implements Parcelable {
|
||||
/**
|
||||
* Target for NFC Forum Type 1 compliant tag.
|
||||
* <p>This is based on Jewel/Topaz technology
|
||||
*/
|
||||
public static final String TARGET_TYPE_1 = "type_1";
|
||||
|
||||
/**
|
||||
* Target for NFC Forum Type 2 compliant tag.
|
||||
* <p>This is based on Mifare Ultralight technology.
|
||||
*/
|
||||
public static final String TARGET_TYPE_2 = "type_2";
|
||||
|
||||
/**
|
||||
* Target for NFC Forum Type 3 compliant tag.
|
||||
* <p>This is based on Felica technology.
|
||||
*/
|
||||
public static final String TARGET_TYPE_3 = "type_3";
|
||||
|
||||
/**
|
||||
* Target for NFC Forum Type 4 compliant tag.
|
||||
* <p>This is based on Mifare Desfire technology.
|
||||
*/
|
||||
public static final String TARGET_TYPE_4 = "type_4";
|
||||
|
||||
/**
|
||||
* Target for NFC Forum Enabled: Mifare Classic tag.
|
||||
* <p>This is not strictly a NFC Forum tag type, but is a common
|
||||
* NDEF message container.
|
||||
*/
|
||||
public static final String TARGET_MIFARE_CLASSIC = "type_mifare_classic";
|
||||
|
||||
/**
|
||||
* Any other target.
|
||||
*/
|
||||
public static final String TARGET_OTHER = "other";
|
||||
|
||||
private final String[] mNdefTargets;
|
||||
private final NdefMessage[][] mMessages; // one NdefMessage[] per NDEF target
|
||||
private NdefMessage[] mFlatMessages; // collapsed mMessages, built lazily, protected by (this)
|
||||
|
||||
/**
|
||||
* Hidden constructor to be used by NFC service only.
|
||||
* @hide
|
||||
*/
|
||||
public NdefTag(byte[] id, String[] rawTargets, byte[] pollBytes, byte[] activationBytes,
|
||||
int serviceHandle, String[] ndefTargets, NdefMessage[][] messages) {
|
||||
super(id, true, rawTargets, pollBytes, activationBytes, serviceHandle);
|
||||
if (ndefTargets == null || messages == null) {
|
||||
throw new IllegalArgumentException("ndefTargets or messages cannot be null");
|
||||
}
|
||||
if (ndefTargets.length != messages.length){
|
||||
throw new IllegalArgumentException("ndefTargets and messages arrays must match");
|
||||
}
|
||||
for (NdefMessage[] ms : messages) {
|
||||
if (ms == null) {
|
||||
throw new IllegalArgumentException("messages elements cannot be null");
|
||||
}
|
||||
}
|
||||
mNdefTargets = ndefTargets;
|
||||
mMessages = messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a mock NdefTag.
|
||||
* <p>This is an application constructed tag, so NfcAdapter methods on this
|
||||
* Tag such as {@link NfcAdapter#createRawTagConnection} will fail with
|
||||
* {@link IllegalArgumentException} since it does not represent a physical Tag.
|
||||
* <p>This constructor might be useful for mock testing.
|
||||
* @param id The tag identifier, can be null
|
||||
* @param rawTargets must not be null
|
||||
* @param pollBytes can be null
|
||||
* @param activationBytes can be null
|
||||
* @param ndefTargets NDEF target array, such as {TARGET_TYPE_2}, cannot be null
|
||||
* @param messages messages, one array per NDEF target, cannot be null
|
||||
* @return freshly constructed NdefTag
|
||||
*/
|
||||
public static NdefTag createMockNdefTag(byte[] id, String[] rawTargets, byte[] pollBytes,
|
||||
byte[] activationBytes, String[] ndefTargets, NdefMessage[][] messages) {
|
||||
// set serviceHandle to 0 to indicate mock tag
|
||||
return new NdefTag(id, rawTargets, pollBytes, activationBytes, 0, ndefTargets, messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all NDEF Messages.
|
||||
* <p>
|
||||
* This retrieves the NDEF Messages that were found on the Tag at discovery
|
||||
* time. It does not cause any further RF activity, and does not block.
|
||||
* <p>
|
||||
* Most tags only contain a single NDEF message.
|
||||
*
|
||||
* @return NDEF Messages found at Tag discovery
|
||||
*/
|
||||
public NdefMessage[] getNdefMessages() {
|
||||
// common-case optimization
|
||||
if (mMessages.length == 1) {
|
||||
return mMessages[0];
|
||||
}
|
||||
|
||||
// return cached flat array
|
||||
synchronized(this) {
|
||||
if (mFlatMessages != null) {
|
||||
return mFlatMessages;
|
||||
}
|
||||
// not cached - build a flat array
|
||||
int sz = 0;
|
||||
for (NdefMessage[] ms : mMessages) {
|
||||
sz += ms.length;
|
||||
}
|
||||
mFlatMessages = new NdefMessage[sz];
|
||||
int i = 0;
|
||||
for (NdefMessage[] ms : mMessages) {
|
||||
System.arraycopy(ms, 0, mFlatMessages, i, ms.length);
|
||||
i += ms.length;
|
||||
}
|
||||
return mFlatMessages;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get only the NDEF Messages from a single NDEF target on a tag.
|
||||
* <p>
|
||||
* This retrieves the NDEF Messages that were found on the Tag at discovery
|
||||
* time. It does not cause any further RF activity, and does not block.
|
||||
* <p>
|
||||
* Most tags only contain a single NDEF message.
|
||||
*
|
||||
* @param target one of targets strings provided by getNdefTargets()
|
||||
* @return NDEF Messages found at Tag discovery
|
||||
*/
|
||||
public NdefMessage[] getNdefMessages(String target) {
|
||||
for (int i=0; i<mNdefTargets.length; i++) {
|
||||
if (target.equals(mNdefTargets[i])) {
|
||||
return mMessages[i];
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("target (" + target + ") not found");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the NDEF targets on this Tag that support NDEF messages.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String[] getNdefTargets() {
|
||||
return mNdefTargets;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
// Tag fields
|
||||
dest.writeInt(mIsNdef ? 1 : 0);
|
||||
writeBytesWithNull(dest, mId);
|
||||
dest.writeInt(mRawTargets.length);
|
||||
dest.writeStringArray(mRawTargets);
|
||||
writeBytesWithNull(dest, mPollBytes);
|
||||
writeBytesWithNull(dest, mActivationBytes);
|
||||
dest.writeInt(mServiceHandle);
|
||||
|
||||
// NdefTag fields
|
||||
dest.writeInt(mNdefTargets.length);
|
||||
dest.writeStringArray(mNdefTargets);
|
||||
dest.writeInt(mMessages.length);
|
||||
for (NdefMessage[] ms : mMessages) {
|
||||
dest.writeInt(ms.length);
|
||||
dest.writeTypedArray(ms, flags);
|
||||
}
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<NdefTag> CREATOR =
|
||||
new Parcelable.Creator<NdefTag>() {
|
||||
public NdefTag createFromParcel(Parcel in) {
|
||||
boolean isNdef = (in.readInt() == 1);
|
||||
if (!isNdef) {
|
||||
throw new IllegalArgumentException("Creating NdefTag from Tag parcel");
|
||||
}
|
||||
|
||||
// Tag fields
|
||||
byte[] id = readBytesWithNull(in);
|
||||
String[] rawTargets = new String[in.readInt()];
|
||||
in.readStringArray(rawTargets);
|
||||
byte[] pollBytes = readBytesWithNull(in);
|
||||
byte[] activationBytes = readBytesWithNull(in);
|
||||
int serviceHandle = in.readInt();
|
||||
|
||||
// NdefTag fields
|
||||
String[] ndefTargets = new String[in.readInt()];
|
||||
in.readStringArray(ndefTargets);
|
||||
NdefMessage[][] messages = new NdefMessage[in.readInt()][];
|
||||
for (int i=0; i<messages.length; i++) {
|
||||
messages[i] = new NdefMessage[in.readInt()];
|
||||
in.readTypedArray(messages[i], NdefMessage.CREATOR);
|
||||
}
|
||||
return new NdefTag(id, rawTargets, pollBytes, activationBytes, serviceHandle,
|
||||
ndefTargets, messages);
|
||||
}
|
||||
public NdefTag[] newArray(int size) {
|
||||
return new NdefTag[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,25 +1,26 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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 android.nfc;
|
||||
|
||||
import java.lang.UnsupportedOperationException;
|
||||
|
||||
import android.annotation.SdkConstant;
|
||||
import android.annotation.SdkConstant.SdkConstantType;
|
||||
import android.app.ActivityThread;
|
||||
import android.content.Context;
|
||||
import android.content.pm.IPackageManager;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.nfc.INfcAdapter;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
@@ -39,6 +40,12 @@ public final class NfcAdapter {
|
||||
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
|
||||
public static final String ACTION_TAG_DISCOVERED = "android.nfc.action.TAG_DISCOVERED";
|
||||
|
||||
/**
|
||||
* Broadcast to only the activity that handles ACTION_TAG_DISCOVERED
|
||||
* @hide
|
||||
*/
|
||||
public static final String ACTION_TAG_LEFT_FIELD = "android.nfc.action.TAG_LOST";
|
||||
|
||||
/**
|
||||
* Mandatory Tag extra for the ACTION_TAG intents.
|
||||
* @hide
|
||||
@@ -169,6 +176,14 @@ public final class NfcAdapter {
|
||||
mService = service;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the binder interface to the service.
|
||||
* @hide
|
||||
*/
|
||||
public INfcAdapter getService() {
|
||||
return mService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to check if this device has FEATURE_NFC, but without using
|
||||
* a context.
|
||||
@@ -230,8 +245,11 @@ public final class NfcAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
/** NFC service dead - attempt best effort recovery */
|
||||
/*package*/ void attemptDeadServiceRecovery(Exception e) {
|
||||
/**
|
||||
* NFC service dead - attempt best effort recovery
|
||||
* @hide
|
||||
*/
|
||||
public void attemptDeadServiceRecovery(Exception e) {
|
||||
Log.e(TAG, "NFC service dead - attempting to recover", e);
|
||||
INfcAdapter service = getServiceInterface();
|
||||
if (service == null) {
|
||||
@@ -301,16 +319,41 @@ public final class NfcAdapter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a raw tag connection to the default Target
|
||||
* Set the NDEF Message that this NFC adapter should appear as to Tag
|
||||
* readers.
|
||||
* <p>
|
||||
* Any Tag reader can read the contents of the local tag when it is in
|
||||
* proximity, without any further user confirmation.
|
||||
* <p>
|
||||
* The implementation of this method must either
|
||||
* <ul>
|
||||
* <li>act as a passive tag containing this NDEF message
|
||||
* <li>provide the NDEF message on over LLCP to peer NFC adapters
|
||||
* </ul>
|
||||
* The NDEF message is preserved across reboot.
|
||||
* <p>Requires {@link android.Manifest.permission#NFC} permission.
|
||||
*
|
||||
* @param message NDEF message to make public
|
||||
* @hide
|
||||
*/
|
||||
public RawTagConnection createRawTagConnection(Tag tag) {
|
||||
if (tag.mServiceHandle == 0) {
|
||||
throw new IllegalArgumentException("mock tag cannot be used for connections");
|
||||
}
|
||||
public void setLocalNdefMessage(NdefMessage message) {
|
||||
try {
|
||||
return new RawTagConnection(this, tag);
|
||||
mService.localSet(message);
|
||||
} catch (RemoteException e) {
|
||||
attemptDeadServiceRecovery(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the NDEF Message that this adapter appears as to Tag readers.
|
||||
* <p>Requires {@link android.Manifest.permission#NFC} permission.
|
||||
*
|
||||
* @return NDEF Message that is publicly readable
|
||||
* @hide
|
||||
*/
|
||||
public NdefMessage getLocalNdefMessage() {
|
||||
try {
|
||||
return mService.localGet();
|
||||
} catch (RemoteException e) {
|
||||
attemptDeadServiceRecovery(e);
|
||||
return null;
|
||||
@@ -318,52 +361,14 @@ public final class NfcAdapter {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a raw tag connection to the specified Target
|
||||
* <p>Requires {@link android.Manifest.permission#NFC} permission.
|
||||
* Create an Nfc Secure Element Connection
|
||||
* @hide
|
||||
*/
|
||||
public RawTagConnection createRawTagConnection(Tag tag, String target) {
|
||||
if (tag.mServiceHandle == 0) {
|
||||
throw new IllegalArgumentException("mock tag cannot be used for connections");
|
||||
}
|
||||
public NfcSecureElement createNfcSecureElementConnection() {
|
||||
try {
|
||||
return new RawTagConnection(this, tag, target);
|
||||
return new NfcSecureElement(mService.getNfcSecureElementInterface());
|
||||
} catch (RemoteException e) {
|
||||
attemptDeadServiceRecovery(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an NDEF tag connection to the default Target
|
||||
* <p>Requires {@link android.Manifest.permission#NFC} permission.
|
||||
* @hide
|
||||
*/
|
||||
public NdefTagConnection createNdefTagConnection(NdefTag tag) {
|
||||
if (tag.mServiceHandle == 0) {
|
||||
throw new IllegalArgumentException("mock tag cannot be used for connections");
|
||||
}
|
||||
try {
|
||||
return new NdefTagConnection(this, tag);
|
||||
} catch (RemoteException e) {
|
||||
attemptDeadServiceRecovery(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an NDEF tag connection to the specified Target
|
||||
* <p>Requires {@link android.Manifest.permission#NFC} permission.
|
||||
* @hide
|
||||
*/
|
||||
public NdefTagConnection createNdefTagConnection(NdefTag tag, String target) {
|
||||
if (tag.mServiceHandle == 0) {
|
||||
throw new IllegalArgumentException("mock tag cannot be used for connections");
|
||||
}
|
||||
try {
|
||||
return new NdefTagConnection(this, tag, target);
|
||||
} catch (RemoteException e) {
|
||||
attemptDeadServiceRecovery(e);
|
||||
Log.e(TAG, "createNfcSecureElementConnection failed", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
138
core/java/android/nfc/NfcSecureElement.java
Executable file
138
core/java/android/nfc/NfcSecureElement.java
Executable file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* 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 android.nfc;
|
||||
|
||||
import android.nfc.technology.TagTechnology;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
//import android.util.Log;
|
||||
|
||||
/**
|
||||
* This class provides the primary API for managing all aspects Secure Element.
|
||||
* Get an instance of this class by calling
|
||||
* Context.getSystemService(Context.NFC_SERVICE).
|
||||
* @hide
|
||||
*/
|
||||
public final class NfcSecureElement {
|
||||
|
||||
private static final String TAG = "NfcSecureElement";
|
||||
|
||||
private INfcSecureElement mService;
|
||||
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public NfcSecureElement(INfcSecureElement mSecureElementService) {
|
||||
mService = mSecureElementService;
|
||||
}
|
||||
|
||||
public int openSecureElementConnection(String seType) throws IOException {
|
||||
if (seType.equals("SmartMX")) {
|
||||
try {
|
||||
int handle = mService.openSecureElementConnection();
|
||||
// Handle potential errors
|
||||
if (handle != 0) {
|
||||
return handle;
|
||||
} else {
|
||||
throw new IOException("SmartMX connection not allowed");
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "RemoteException in openSecureElementConnection(): ", e);
|
||||
return 0;
|
||||
}
|
||||
|
||||
} else if (seType.equals("UICC")) {
|
||||
return 0;
|
||||
} else {
|
||||
throw new IOException("Wrong Secure Element type");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public byte [] exchangeAPDU(int handle,byte [] data) throws IOException {
|
||||
|
||||
|
||||
// Perform exchange APDU
|
||||
try {
|
||||
byte[] response = mService.exchangeAPDU(handle, data);
|
||||
// Handle potential errors
|
||||
if (response == null) {
|
||||
throw new IOException("Exchange APDU failed");
|
||||
}
|
||||
return response;
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "RemoteException in exchangeAPDU(): ", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void closeSecureElementConnection(int handle) throws IOException {
|
||||
|
||||
try {
|
||||
int status = mService.closeSecureElementConnection(handle);
|
||||
// Handle potential errors
|
||||
if (ErrorCodes.isError(status)) {
|
||||
throw new IOException("Error during the conection close");
|
||||
};
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "RemoteException in closeSecureElement(): ", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns target type. constants.
|
||||
*
|
||||
* @return Secure Element technology type. The possible values are defined in
|
||||
* {@link TagTechnology}
|
||||
*
|
||||
*/
|
||||
public int[] getSecureElementTechList(int handle) throws IOException {
|
||||
try {
|
||||
return mService.getSecureElementTechList(handle);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "RemoteException in getType(): ", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns Secure Element UID.
|
||||
*
|
||||
* @return Secure Element UID.
|
||||
*/
|
||||
public byte[] getSecureElementUid(int handle) throws IOException {
|
||||
|
||||
byte[] uid = null;
|
||||
try {
|
||||
uid = mService.getSecureElementUid(handle);
|
||||
// Handle potential errors
|
||||
if (uid == null) {
|
||||
throw new IOException("Get Secure Element UID failed");
|
||||
}
|
||||
return uid;
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "RemoteException in getType(): ", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,8 +16,20 @@
|
||||
|
||||
package android.nfc;
|
||||
|
||||
import android.nfc.technology.IsoDep;
|
||||
import android.nfc.technology.MifareClassic;
|
||||
import android.nfc.technology.NfcV;
|
||||
import android.nfc.technology.Ndef;
|
||||
import android.nfc.technology.NfcA;
|
||||
import android.nfc.technology.NfcB;
|
||||
import android.nfc.technology.NfcF;
|
||||
import android.nfc.technology.TagTechnology;
|
||||
import android.os.Bundle;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Represents a (generic) discovered tag.
|
||||
@@ -30,13 +42,13 @@ import android.os.Parcelable;
|
||||
* {@link Tag} objects are passed to applications via the {@link NfcAdapter#EXTRA_TAG} extra
|
||||
* in {@link NfcAdapter#ACTION_TAG_DISCOVERED} intents. A {@link Tag} object is immutable
|
||||
* and represents the state of the tag at the time of discovery. It can be
|
||||
* directly queried for its UID and Type, or used to create a {@link RawTagConnection}
|
||||
* (with {@link NfcAdapter#createRawTagConnection createRawTagConnection()}).
|
||||
* directly queried for its UID and Type, or used to create a {@link TagTechnology}
|
||||
* (with {@link Tag#getTechnology(int)}).
|
||||
* <p>
|
||||
* A {@link Tag} can be used to create a {@link RawTagConnection} only while the tag is in
|
||||
* A {@link Tag} can be used to create a {@link TagTechnology} only while the tag is in
|
||||
* range. If it is removed and then returned to range, then the most recent
|
||||
* {@link Tag} object (in {@link NfcAdapter#ACTION_TAG_DISCOVERED}) should be used to create a
|
||||
* {@link RawTagConnection}.
|
||||
* {@link TagTechnology}.
|
||||
* <p>This is an immutable data class. All properties are set at Tag discovery
|
||||
* time and calls on this class will retrieve those read-only properties, and
|
||||
* not cause any further RF activity or block. Note however that arrays passed to and
|
||||
@@ -44,78 +56,39 @@ import android.os.Parcelable;
|
||||
* @hide
|
||||
*/
|
||||
public class Tag implements Parcelable {
|
||||
/**
|
||||
* ISO 14443-3A technology.
|
||||
* <p>
|
||||
* Includes Topaz (which is -3A compatible)
|
||||
*/
|
||||
public static final String TARGET_ISO_14443_3A = "iso14443_3a";
|
||||
|
||||
/**
|
||||
* ISO 14443-3B technology.
|
||||
*/
|
||||
public static final String TARGET_ISO_14443_3B = "iso14443_3b";
|
||||
|
||||
/**
|
||||
* ISO 14443-4 technology.
|
||||
*/
|
||||
public static final String TARGET_ISO_14443_4 = "iso14443_4";
|
||||
|
||||
/**
|
||||
* ISO 15693 technology, commonly known as RFID.
|
||||
*/
|
||||
public static final String TARGET_ISO_15693 = "iso15693";
|
||||
|
||||
/**
|
||||
* JIS X-6319-4 technology, commonly known as Felica.
|
||||
*/
|
||||
public static final String TARGET_JIS_X_6319_4 = "jis_x_6319_4";
|
||||
|
||||
/**
|
||||
* Any other technology.
|
||||
*/
|
||||
public static final String TARGET_OTHER = "other";
|
||||
|
||||
/*package*/ final boolean mIsNdef;
|
||||
/*package*/ final byte[] mId;
|
||||
/*package*/ final String[] mRawTargets;
|
||||
/*package*/ final byte[] mPollBytes;
|
||||
/*package*/ final byte[] mActivationBytes;
|
||||
/*package*/ final int[] mTechList;
|
||||
/*package*/ final Bundle[] mTechExtras;
|
||||
/*package*/ final int mServiceHandle; // for use by NFC service, 0 indicates a mock
|
||||
|
||||
/**
|
||||
* Hidden constructor to be used by NFC service and internal classes.
|
||||
* @hide
|
||||
*/
|
||||
public Tag(byte[] id, boolean isNdef, String[] rawTargets, byte[] pollBytes,
|
||||
byte[] activationBytes, int serviceHandle) {
|
||||
if (rawTargets == null) {
|
||||
public Tag(byte[] id, int[] techList, Bundle[] techListExtras, int serviceHandle) {
|
||||
if (techList == null) {
|
||||
throw new IllegalArgumentException("rawTargets cannot be null");
|
||||
}
|
||||
mIsNdef = isNdef;
|
||||
mId = id;
|
||||
mRawTargets = rawTargets;
|
||||
mPollBytes = pollBytes;
|
||||
mActivationBytes = activationBytes;
|
||||
mTechList = Arrays.copyOf(techList, techList.length);
|
||||
// Ensure mTechExtras is as long as mTechList
|
||||
mTechExtras = Arrays.copyOf(techListExtras, techList.length);
|
||||
mServiceHandle = serviceHandle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a mock Tag.
|
||||
* <p>This is an application constructed tag, so NfcAdapter methods on this
|
||||
* Tag such as {@link NfcAdapter#createRawTagConnection} will fail with
|
||||
* Tag such as {@link #getTechnology} may fail with
|
||||
* {@link IllegalArgumentException} since it does not represent a physical Tag.
|
||||
* <p>This constructor might be useful for mock testing.
|
||||
* @param id The tag identifier, can be null
|
||||
* @param rawTargets must not be null
|
||||
* @param pollBytes can be null
|
||||
* @param activationBytes can be null
|
||||
* @param techList must not be null
|
||||
* @return freshly constructed tag
|
||||
*/
|
||||
public static Tag createMockTag(byte[] id, String[] rawTargets, byte[] pollBytes,
|
||||
byte[] activationBytes) {
|
||||
public static Tag createMockTag(byte[] id, int[] techList, Bundle[] techListExtras) {
|
||||
// set serviceHandle to 0 to indicate mock tag
|
||||
return new Tag(id, false, rawTargets, pollBytes, activationBytes, 0);
|
||||
return new Tag(id, techList, techListExtras, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,16 +99,6 @@ public class Tag implements Parcelable {
|
||||
return mServiceHandle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the available targets that this NFC adapter can use to create
|
||||
* a RawTagConnection.
|
||||
*
|
||||
* @return raw targets, will not be null
|
||||
*/
|
||||
public String[] getRawTargets() {
|
||||
return mRawTargets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Tag Identifier (if it has one).
|
||||
* <p>Tag ID is usually a serial number for the tag.
|
||||
@@ -147,37 +110,64 @@ public class Tag implements Parcelable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the low-level bytes returned by this Tag at poll-time.
|
||||
* <p>These can be used to help with advanced identification of a Tag.
|
||||
* <p>The meaning of these bytes depends on the Tag technology.
|
||||
* <p>ISO14443-3A: ATQA/SENS_RES
|
||||
* <p>ISO14443-3B: Application data (4 bytes) and Protocol Info (3 bytes) from ATQB/SENSB_RES
|
||||
* <p>JIS_X_6319_4: PAD0 (2 byte), PAD1 (2 byte), MRTI(2 byte), PAD2 (1 byte), RC (2 byte)
|
||||
* <p>ISO15693: response flags (1 byte), DSFID (1 byte)
|
||||
* from SENSF_RES
|
||||
*
|
||||
* @return poll bytes, or null if they do not exist for this Tag technology
|
||||
* @hide
|
||||
* Returns technologies present in the tag that this implementation understands,
|
||||
* or a zero length array if there are no supported technologies on this tag.
|
||||
*/
|
||||
public byte[] getPollBytes() {
|
||||
return mPollBytes;
|
||||
public int[] getTechnologyList() {
|
||||
return Arrays.copyOf(mTechList, mTechList.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the low-level bytes returned by this Tag at activation-time.
|
||||
* <p>These can be used to help with advanced identification of a Tag.
|
||||
* <p>The meaning of these bytes depends on the Tag technology.
|
||||
* <p>ISO14443-3A: SAK/SEL_RES
|
||||
* <p>ISO14443-3B: null
|
||||
* <p>ISO14443-3A & ISO14443-4: SAK/SEL_RES, historical bytes from ATS <TODO: confirm>
|
||||
* <p>ISO14443-3B & ISO14443-4: ATTRIB response
|
||||
* <p>JIS_X_6319_4: null
|
||||
* <p>ISO15693: response flags (1 byte), DSFID (1 byte): null
|
||||
* @return activation bytes, or null if they do not exist for this Tag technology
|
||||
* @hide
|
||||
* Returns the technology, or null if not present
|
||||
*/
|
||||
public byte[] getActivationBytes() {
|
||||
return mActivationBytes;
|
||||
public TagTechnology getTechnology(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;
|
||||
}
|
||||
|
||||
Bundle extras = mTechExtras[pos];
|
||||
NfcAdapter adapter = NfcAdapter.getDefaultAdapter();
|
||||
try {
|
||||
switch (tech) {
|
||||
case TagTechnology.NFC_A: {
|
||||
return new NfcA(adapter, this, extras);
|
||||
}
|
||||
case TagTechnology.NFC_B: {
|
||||
return new NfcB(adapter, this, extras);
|
||||
}
|
||||
case TagTechnology.ISO_DEP: {
|
||||
return new IsoDep(adapter, this, extras);
|
||||
}
|
||||
case TagTechnology.NFC_V: {
|
||||
return new NfcV(adapter, this, extras);
|
||||
}
|
||||
case TagTechnology.TYPE_1:
|
||||
case TagTechnology.TYPE_2:
|
||||
case TagTechnology.TYPE_3:
|
||||
case TagTechnology.TYPE_4: {
|
||||
return new Ndef(adapter, this, tech, extras);
|
||||
}
|
||||
case TagTechnology.NFC_F: {
|
||||
return new NfcF(adapter, this, extras);
|
||||
}
|
||||
case TagTechnology.MIFARE_CLASSIC: {
|
||||
return new MifareClassic(adapter, this, extras);
|
||||
}
|
||||
|
||||
default: {
|
||||
throw new UnsupportedOperationException("Tech " + tech + " not supported");
|
||||
}
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -185,13 +175,9 @@ public class Tag implements Parcelable {
|
||||
StringBuilder sb = new StringBuilder("TAG ")
|
||||
.append("uid = ")
|
||||
.append(mId)
|
||||
.append(" poll ")
|
||||
.append(mPollBytes)
|
||||
.append(" activation ")
|
||||
.append(mActivationBytes)
|
||||
.append(" Raw [");
|
||||
for (String s : mRawTargets) {
|
||||
sb.append(s)
|
||||
.append(" Tech [");
|
||||
for (int i : mTechList) {
|
||||
sb.append(i)
|
||||
.append(", ");
|
||||
}
|
||||
return sb.toString();
|
||||
@@ -221,37 +207,32 @@ public class Tag implements Parcelable {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(mIsNdef ? 1 : 0);
|
||||
writeBytesWithNull(dest, mId);
|
||||
dest.writeInt(mRawTargets.length);
|
||||
dest.writeStringArray(mRawTargets);
|
||||
writeBytesWithNull(dest, mPollBytes);
|
||||
writeBytesWithNull(dest, mActivationBytes);
|
||||
dest.writeInt(mTechList.length);
|
||||
dest.writeIntArray(mTechList);
|
||||
dest.writeTypedArray(mTechExtras, 0);
|
||||
dest.writeInt(mServiceHandle);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<Tag> CREATOR =
|
||||
new Parcelable.Creator<Tag>() {
|
||||
@Override
|
||||
public Tag createFromParcel(Parcel in) {
|
||||
boolean isNdef = (in.readInt() == 1);
|
||||
if (isNdef) {
|
||||
throw new IllegalArgumentException("Creating Tag from NdefTag parcel");
|
||||
}
|
||||
// Tag fields
|
||||
byte[] id = Tag.readBytesWithNull(in);
|
||||
String[] rawTargets = new String[in.readInt()];
|
||||
in.readStringArray(rawTargets);
|
||||
byte[] pollBytes = Tag.readBytesWithNull(in);
|
||||
byte[] activationBytes = Tag.readBytesWithNull(in);
|
||||
int[] techList = new int[in.readInt()];
|
||||
in.readIntArray(techList);
|
||||
Bundle[] techExtras = in.createTypedArray(Bundle.CREATOR);
|
||||
int serviceHandle = in.readInt();
|
||||
|
||||
return new Tag(id, isNdef, rawTargets, pollBytes, activationBytes, serviceHandle);
|
||||
return new Tag(id, techList, techExtras, serviceHandle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Tag[] newArray(int size) {
|
||||
return new Tag[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,31 +14,25 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.nfc;
|
||||
package android.nfc.technology;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import android.nfc.INfcAdapter;
|
||||
import android.nfc.INfcTag;
|
||||
import android.nfc.NfcAdapter;
|
||||
import android.nfc.Tag;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* A low-level connection to a {@link Tag} target.
|
||||
* <p>You can acquire this kind of connection with {@link NfcAdapter#createRawTagConnection
|
||||
* createRawTagConnection()}. Use the connection to send and receive data with {@link #transceive
|
||||
* transceive()}.
|
||||
* <p>
|
||||
* Applications must implement their own protocol stack on top of {@link #transceive transceive()}.
|
||||
*
|
||||
* <p class="note"><strong>Note:</strong>
|
||||
* Use of this class requires the {@link android.Manifest.permission#NFC}
|
||||
* permission.
|
||||
* @hide
|
||||
* A base class for tag technologies that are built on top of transceive().
|
||||
*/
|
||||
public class RawTagConnection {
|
||||
/* package */ abstract class BasicTagTechnology implements TagTechnology {
|
||||
|
||||
/*package*/ final Tag mTag;
|
||||
/*package*/ boolean mIsConnected;
|
||||
/*package*/ String mSelectedTarget;
|
||||
/*package*/ int mSelectedTechnology;
|
||||
private final NfcAdapter mAdapter;
|
||||
|
||||
// Following fields are final after construction, except for
|
||||
@@ -49,30 +43,40 @@ public class RawTagConnection {
|
||||
|
||||
private static final String TAG = "NFC";
|
||||
|
||||
/*package*/ RawTagConnection(NfcAdapter adapter, Tag tag, String target) throws RemoteException {
|
||||
String[] targets = tag.getRawTargets();
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public BasicTagTechnology(NfcAdapter adapter, Tag tag, int tech) throws RemoteException {
|
||||
int[] techList = tag.getTechnologyList();
|
||||
int i;
|
||||
|
||||
// Check target validity
|
||||
for (i=0;i<targets.length;i++) {
|
||||
if (target.equals(targets[i])) {
|
||||
for (i = 0; i < techList.length; i++) {
|
||||
if (tech == techList[i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= targets.length) {
|
||||
// Target not found
|
||||
throw new IllegalArgumentException();
|
||||
if (i >= techList.length) {
|
||||
// Technology not found
|
||||
throw new IllegalArgumentException("Technology " + tech + " not present on tag " + tag);
|
||||
}
|
||||
|
||||
mAdapter = adapter;
|
||||
mService = mAdapter.mService;
|
||||
mTagService = mService.getNfcTagInterface();
|
||||
mService = mAdapter.getService();
|
||||
try {
|
||||
mTagService = mService.getNfcTagInterface();
|
||||
} catch (RemoteException e) {
|
||||
attemptDeadServiceRecovery(e);
|
||||
}
|
||||
mTag = tag;
|
||||
mSelectedTarget = target;
|
||||
mSelectedTechnology = tech;
|
||||
}
|
||||
|
||||
/*package*/ RawTagConnection(NfcAdapter adapter, Tag tag) throws RemoteException {
|
||||
this(adapter, tag, tag.getRawTargets()[0]);
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public BasicTagTechnology(NfcAdapter adapter, Tag tag) throws RemoteException {
|
||||
this(adapter, tag, tag.getTechnologyList()[0]);
|
||||
}
|
||||
|
||||
/** NFC service dead - attempt best effort recovery */
|
||||
@@ -80,7 +84,7 @@ public class RawTagConnection {
|
||||
mAdapter.attemptDeadServiceRecovery(e);
|
||||
/* assigning to mService is not thread-safe, but this is best-effort code
|
||||
* and on a well-behaved system should never happen */
|
||||
mService = mAdapter.mService;
|
||||
mService = mAdapter.getService();
|
||||
try {
|
||||
mTagService = mService.getNfcTagInterface();
|
||||
} catch (RemoteException e2) {
|
||||
@@ -92,6 +96,7 @@ public class RawTagConnection {
|
||||
* Get the {@link Tag} this connection is associated with.
|
||||
* <p>Requires {@link android.Manifest.permission#NFC} permission.
|
||||
*/
|
||||
@Override
|
||||
public Tag getTag() {
|
||||
return mTag;
|
||||
}
|
||||
@@ -99,8 +104,9 @@ public class RawTagConnection {
|
||||
/**
|
||||
* <p>Requires {@link android.Manifest.permission#NFC} permission.
|
||||
*/
|
||||
public String getTagTarget() {
|
||||
return mSelectedTarget;
|
||||
@Override
|
||||
public int getTechnologyId() {
|
||||
return mSelectedTechnology;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,7 +125,7 @@ public class RawTagConnection {
|
||||
}
|
||||
|
||||
try {
|
||||
return mTagService.isPresent(mTag.mServiceHandle);
|
||||
return mTagService.isPresent(mTag.getServiceHandle());
|
||||
} catch (RemoteException e) {
|
||||
attemptDeadServiceRecovery(e);
|
||||
return false;
|
||||
@@ -136,6 +142,7 @@ public class RawTagConnection {
|
||||
* <p>Requires {@link android.Manifest.permission#NFC} permission.
|
||||
* @throws IOException if the target is lost, or connect canceled
|
||||
*/
|
||||
@Override
|
||||
public void connect() throws IOException {
|
||||
//TODO(nxp): enforce exclusivity
|
||||
mIsConnected = true;
|
||||
@@ -151,10 +158,11 @@ public class RawTagConnection {
|
||||
* calls to {@link #transceive transceive()} or {@link #connect} will fail.
|
||||
* <p>Requires {@link android.Manifest.permission#NFC} permission.
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
mIsConnected = false;
|
||||
try {
|
||||
mTagService.close(mTag.mServiceHandle);
|
||||
mTagService.close(mTag.getServiceHandle());
|
||||
} catch (RemoteException e) {
|
||||
attemptDeadServiceRecovery(e);
|
||||
}
|
||||
@@ -173,7 +181,7 @@ public class RawTagConnection {
|
||||
*/
|
||||
public byte[] transceive(byte[] data) throws IOException {
|
||||
try {
|
||||
byte[] response = mTagService.transceive(mTag.mServiceHandle, data);
|
||||
byte[] response = mTagService.transceive(mTag.getServiceHandle(), data);
|
||||
if (response == null) {
|
||||
throw new IOException("transcieve failed");
|
||||
}
|
||||
80
core/java/android/nfc/technology/IsoDep.java
Normal file
80
core/java/android/nfc/technology/IsoDep.java
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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 android.nfc.technology;
|
||||
|
||||
import android.nfc.NfcAdapter;
|
||||
import android.nfc.Tag;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A low-level connection to a {@link Tag} using the ISO-DEP technology, also known as
|
||||
* ISO1443-4.
|
||||
*
|
||||
* <p>You can acquire this kind of connection with {@link Tag#getTechnology(int)}.
|
||||
* Use this class to send and receive data with {@link #transceive transceive()}.
|
||||
*
|
||||
* <p>Applications must implement their own protocol stack on top of
|
||||
* {@link #transceive transceive()}.
|
||||
*
|
||||
* <p class="note"><strong>Note:</strong>
|
||||
* Use of this class requires the {@link android.Manifest.permission#NFC}
|
||||
* permission.
|
||||
*/
|
||||
public final class IsoDep extends BasicTagTechnology {
|
||||
/** @hide */
|
||||
public static final String EXTRA_ATTRIB = "attrib";
|
||||
/** @hide */
|
||||
public static final String EXTRA_HIST_BYTES = "histbytes";
|
||||
|
||||
private byte[] mAttrib = null;
|
||||
private byte[] mHistBytes = null;
|
||||
|
||||
public IsoDep(NfcAdapter adapter, Tag tag, Bundle extras)
|
||||
throws RemoteException {
|
||||
super(adapter, tag, TagTechnology.ISO_DEP);
|
||||
if (extras != null) {
|
||||
mAttrib = extras.getByteArray(EXTRA_ATTRIB);
|
||||
mHistBytes = extras.getByteArray(EXTRA_HIST_BYTES);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 3A only
|
||||
*/
|
||||
public byte[] getHistoricalBytes() { return mHistBytes; }
|
||||
|
||||
/**
|
||||
* 3B only
|
||||
*/
|
||||
public byte[] getAttrib() { return mAttrib; }
|
||||
|
||||
/**
|
||||
* Attempts to select the given application on the tag. Note that this only works
|
||||
* if the tag supports ISO7816-4, which not all IsoDep tags support. If the tag doesn't
|
||||
* support ISO7816-4 this will throw {@link UnsupportedOperationException}.
|
||||
*
|
||||
* This method requires that you call {@link #connect} before calling it.
|
||||
*
|
||||
* @throws IOException, UnsupportedOperationException
|
||||
*/
|
||||
public void selectAid(byte[] aid) throws IOException, UnsupportedOperationException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
291
core/java/android/nfc/technology/MifareClassic.java
Normal file
291
core/java/android/nfc/technology/MifareClassic.java
Normal file
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
* 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 android.nfc.technology;
|
||||
|
||||
import android.nfc.NfcAdapter;
|
||||
import android.nfc.Tag;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Concrete class for TagTechnology.MIFARE_CLASSIC
|
||||
*
|
||||
* Mifare classic has n sectors, with varying sizes, although
|
||||
* they are at least the same pattern for any one mifare classic
|
||||
* product. Each sector has two keys. Authentication with the correct
|
||||
* key is needed before access to any sector.
|
||||
*
|
||||
* Each sector has k blocks.
|
||||
* Block size is constant across the whole mifare classic family.
|
||||
*/
|
||||
public final class MifareClassic extends BasicTagTechnology {
|
||||
/**
|
||||
* The well-known, default factory MIFARE read key.
|
||||
* Use this key to effectively make the payload in this sector
|
||||
* public.
|
||||
*/
|
||||
public static final byte[] DEFAULT_KEY_FACTORY =
|
||||
{(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF};
|
||||
public static final byte[] DEFAULT_KEY_ZERO =
|
||||
{(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00};
|
||||
/**
|
||||
* The well-known, default Mifare Application Directory read key.
|
||||
*/
|
||||
public static final byte[] DEFAULT_KEY_MAD =
|
||||
{(byte)0xA0,(byte)0xA1,(byte)0xA2,(byte)0xA3,(byte)0xA4,(byte)0xA5};
|
||||
/**
|
||||
* The well-known, default read key for NDEF data on a Mifare Classic
|
||||
*/
|
||||
public static final byte[] DEFAULT_KEY_NFC_FORUM =
|
||||
{(byte)0xD3,(byte)0xF7,(byte)0xD3,(byte)0xF7,(byte)0xD3,(byte)0xF7};
|
||||
|
||||
public static final int TYPE_CLASSIC = 0;
|
||||
public static final int TYPE_PLUS = 1;
|
||||
public static final int TYPE_PRO = 2;
|
||||
public static final int TYPE_DESFIRE = 3;
|
||||
public static final int TYPE_ULTRALIGHT = 4;
|
||||
public static final int TYPE_UNKNOWN = 5;
|
||||
|
||||
public static final int SIZE_1K = 1024;
|
||||
public static final int SIZE_2K = 2048;
|
||||
public static final int SIZE_4K = 4096;
|
||||
public static final int SIZE_MINI = 320;
|
||||
public static final int SIZE_UNKNOWN = 0;
|
||||
|
||||
private boolean mIsEmulated;
|
||||
private int mType;
|
||||
private int mSize;
|
||||
|
||||
public MifareClassic(NfcAdapter adapter, Tag tag, Bundle extras) throws RemoteException {
|
||||
super(adapter, tag, TagTechnology.MIFARE_CLASSIC);
|
||||
|
||||
// Check if this could actually be a Mifare
|
||||
NfcA a = (NfcA) tag.getTechnology(TagTechnology.NFC_A);
|
||||
//short[] ATQA = getATQA(tag);
|
||||
|
||||
mIsEmulated = false;
|
||||
mType = TYPE_UNKNOWN;
|
||||
mSize = SIZE_UNKNOWN;
|
||||
|
||||
switch (a.getSak()) {
|
||||
case 0x00:
|
||||
// could be UL or UL-C
|
||||
mType = TYPE_ULTRALIGHT;
|
||||
break;
|
||||
case 0x08:
|
||||
// Type == classic
|
||||
// Size = 1K
|
||||
mType = TYPE_CLASSIC;
|
||||
mSize = SIZE_1K;
|
||||
break;
|
||||
case 0x09:
|
||||
// Type == classic mini
|
||||
// Size == ?
|
||||
mType = TYPE_CLASSIC;
|
||||
mSize = SIZE_MINI;
|
||||
break;
|
||||
case 0x10:
|
||||
// Type == MF+
|
||||
// Size == 2K
|
||||
// SecLevel = SL2
|
||||
mType = TYPE_PLUS;
|
||||
mSize = SIZE_2K;
|
||||
break;
|
||||
case 0x11:
|
||||
// Type == MF+
|
||||
// Size == 4K
|
||||
// Seclevel = SL2
|
||||
mType = TYPE_PLUS;
|
||||
mSize = SIZE_4K;
|
||||
break;
|
||||
case 0x18:
|
||||
// Type == classic
|
||||
// Size == 4k
|
||||
mType = TYPE_CLASSIC;
|
||||
mSize = SIZE_4K;
|
||||
break;
|
||||
case 0x20:
|
||||
// TODO this really should be a short, not byte
|
||||
if (a.getAtqa()[0] == 0x03) {
|
||||
// Type == DESFIRE
|
||||
mType = TYPE_DESFIRE;
|
||||
} else {
|
||||
// Type == MF+
|
||||
// SL = SL3
|
||||
mType = TYPE_PLUS;
|
||||
mSize = SIZE_UNKNOWN;
|
||||
}
|
||||
break;
|
||||
case 0x28:
|
||||
// Type == MF Classic
|
||||
// Size == 1K
|
||||
// Emulated == true
|
||||
mType = TYPE_CLASSIC;
|
||||
mSize = SIZE_1K;
|
||||
mIsEmulated = true;
|
||||
break;
|
||||
case 0x38:
|
||||
// Type == MF Classic
|
||||
// Size == 4K
|
||||
// Emulated == true
|
||||
mType = TYPE_CLASSIC;
|
||||
mSize = SIZE_4K;
|
||||
mIsEmulated = true;
|
||||
break;
|
||||
case 0x88:
|
||||
// Type == MF Classic
|
||||
// Size == 1K
|
||||
// NXP-tag: false
|
||||
mType = TYPE_CLASSIC;
|
||||
mSize = SIZE_1K;
|
||||
break;
|
||||
case 0x98:
|
||||
case 0xB8:
|
||||
// Type == MF Pro
|
||||
// Size == 4K
|
||||
mType = TYPE_PRO;
|
||||
mSize = SIZE_4K;
|
||||
break;
|
||||
default:
|
||||
// Unknown, not MIFARE
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Immutable data known at discovery time
|
||||
public int getSize() {
|
||||
return mSize;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return mType;
|
||||
}
|
||||
|
||||
public boolean isEmulated() {
|
||||
return mIsEmulated;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getSectorSize(int sector) {
|
||||
return getBlockCount(sector) * 16;
|
||||
}
|
||||
|
||||
public int getBlockCount(int sector) {
|
||||
if (sector >= getSectorCount()) {
|
||||
throw new IllegalArgumentException("this card only has " + getSectorCount() +
|
||||
" sectors");
|
||||
}
|
||||
|
||||
if (sector <= 32) {
|
||||
return 4;
|
||||
} else {
|
||||
return 16;
|
||||
}
|
||||
}
|
||||
|
||||
private byte firstBlockInSector(int sector) {
|
||||
if (sector < 32) {
|
||||
return (byte) ((sector * 4) & 0xff);
|
||||
} else {
|
||||
return (byte) ((32 * 4 + ((sector - 32) * 16)) & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
// Methods that require connect()
|
||||
/**
|
||||
* Authenticate for a given sector.
|
||||
*/
|
||||
public boolean authenticateSector(int sector, byte[] key, boolean keyA) {
|
||||
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
|
||||
cmd[1] = firstBlockInSector(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 ((transceive(cmd) != null)) {
|
||||
return true;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// No need to deal with, will return false anyway
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sector indexing starts at 0.
|
||||
* Block indexing starts at 0, and resets in each sector.
|
||||
* @throws IOException
|
||||
*/
|
||||
public byte[] readBlock(int sector, int block) throws IOException {
|
||||
byte addr = (byte) ((firstBlockInSector(sector) + block) & 0xff);
|
||||
byte[] blockread_cmd = { 0x30, addr }; // phHal_eMifareRead
|
||||
|
||||
// TODO deal with authentication problems
|
||||
return transceive(blockread_cmd);
|
||||
}
|
||||
|
||||
// public byte[] readSector(int sector);
|
||||
//TODO: define an enumeration for access control settings
|
||||
// public int readSectorAccessControl(int sector);
|
||||
|
||||
/**
|
||||
* @throws IOException
|
||||
* @throws NotAuthenticatedException
|
||||
*/
|
||||
/*
|
||||
public void writeBlock(int block, byte[] data);
|
||||
public void writeSector(int block, byte[] sector);
|
||||
public void writeSectorAccessControl(int sector, int access);
|
||||
public void increment(int block);
|
||||
public void decrement(int block);
|
||||
*/
|
||||
}
|
||||
@@ -14,77 +14,54 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.nfc;
|
||||
package android.nfc.technology;
|
||||
|
||||
import android.nfc.ErrorCodes;
|
||||
import android.nfc.FormatException;
|
||||
import android.nfc.NdefMessage;
|
||||
import android.nfc.NfcAdapter;
|
||||
import android.nfc.Tag;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* A connection to an NDEF target on an {@link NdefTag}.
|
||||
* <p>You can acquire this kind of connection with {@link NfcAdapter#createNdefTagConnection
|
||||
* createNdefTagConnection()}. Use the connection to read or write {@link NdefMessage}s.
|
||||
* A high-level connection to a {@link Tag} using one of the NFC type 1, 2, 3, or 4 technologies
|
||||
* to interact with NDEF data. MiFare Classic cards that present NDEF data may also be used
|
||||
* via this class. To determine the exact technology being used call {@link #getTechnologyId()}
|
||||
*
|
||||
* <p>You can acquire this kind of connection with {@link Tag#getTechnology(int)}.
|
||||
*
|
||||
* <p class="note"><strong>Note:</strong>
|
||||
* Use of this class requires the {@link android.Manifest.permission#NFC}
|
||||
* permission.
|
||||
* @hide
|
||||
*/
|
||||
public class NdefTagConnection extends RawTagConnection {
|
||||
public final class Ndef extends BasicTagTechnology {
|
||||
public static final int NDEF_MODE_READ_ONCE = 1;
|
||||
public static final int NDEF_MODE_READ_ONLY = 2;
|
||||
public static final int NDEF_MODE_WRITE_ONCE = 3;
|
||||
public static final int NDEF_MODE_WRITE_MANY = 4;
|
||||
public static final int NDEF_MODE_UNKNOWN = 5;
|
||||
|
||||
private static final String TAG = "NFC";
|
||||
|
||||
/**
|
||||
* Internal constructor, to be used by NfcAdapter
|
||||
* @hide
|
||||
*/
|
||||
/* package private */ NdefTagConnection(NfcAdapter adapter, NdefTag tag, String target) throws RemoteException {
|
||||
super(adapter, tag);
|
||||
String[] targets = tag.getNdefTargets();
|
||||
int i;
|
||||
|
||||
// Check target validity
|
||||
for (i=0; i<targets.length; i++) {
|
||||
if (target.equals(targets[i])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i >= targets.length) {
|
||||
// Target not found
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
public Ndef(NfcAdapter adapter, Tag tag, int tech, Bundle extras) throws RemoteException {
|
||||
super(adapter, tag, tech);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal constructor, to be used by NfcAdapter
|
||||
* @hide
|
||||
* Get the primary NDEF message on this tag. This data is read at discovery time
|
||||
* and does not require a connection.
|
||||
*/
|
||||
/* package private */ NdefTagConnection(NfcAdapter adapter, NdefTag tag) throws RemoteException {
|
||||
this(adapter, tag, tag.getNdefTargets()[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read NDEF message(s).
|
||||
* This will always return the most up to date payload, and can block.
|
||||
* It can be canceled with {@link RawTagConnection#close}.
|
||||
* Most NDEF tags will contain just one NDEF message.
|
||||
* <p>Requires {@link android.Manifest.permission#NFC} permission.
|
||||
* @throws FormatException if the tag is not NDEF formatted
|
||||
* @throws IOException if the target is lost or connection closed
|
||||
* @throws FormatException
|
||||
*/
|
||||
public NdefMessage[] readNdefMessages() throws IOException, FormatException {
|
||||
//TODO(nxp): do not use getLastError(), it is racy
|
||||
public NdefMessage getNdefMessage() throws IOException, FormatException {
|
||||
try {
|
||||
NdefMessage[] msgArray = new NdefMessage[1];
|
||||
NdefMessage msg = mTagService.read(mTag.mServiceHandle);
|
||||
int serviceHandle = mTag.getServiceHandle();
|
||||
NdefMessage msg = mTagService.read(serviceHandle);
|
||||
if (msg == null) {
|
||||
int errorCode = mTagService.getLastError(mTag.mServiceHandle);
|
||||
int errorCode = mTagService.getLastError(serviceHandle);
|
||||
switch (errorCode) {
|
||||
case ErrorCodes.ERROR_IO:
|
||||
throw new IOException();
|
||||
@@ -95,8 +72,7 @@ public class NdefTagConnection extends RawTagConnection {
|
||||
throw new IOException();
|
||||
}
|
||||
}
|
||||
msgArray[0] = msg;
|
||||
return msgArray;
|
||||
return msg;
|
||||
} catch (RemoteException e) {
|
||||
attemptDeadServiceRecovery(e);
|
||||
return null;
|
||||
@@ -104,25 +80,56 @@ public class NdefTagConnection extends RawTagConnection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to write an NDEF message to a tag.
|
||||
* This method will block until the data is written. It can be canceled
|
||||
* with {@link RawTagConnection#close}.
|
||||
* Many tags are write-once, so use this method carefully.
|
||||
* Specification allows for multiple NDEF messages per NDEF tag, but it is
|
||||
* encourage to only write one message, this so API only takes a single
|
||||
* message. Use {@link NdefRecord} to write several records to a single tag.
|
||||
* For write-many tags, use {@link #makeReadOnly} after this method to attempt
|
||||
* to prevent further modification. For write-once tags this is not
|
||||
* necessary.
|
||||
* <p>Requires {@link android.Manifest.permission#NFC} permission.
|
||||
*
|
||||
* @throws FormatException if the tag is not suitable for NDEF messages
|
||||
* @throws IOException if the target is lost or connection closed or the
|
||||
* write failed
|
||||
* Get optional extra NDEF messages.
|
||||
* Some tags may contain extra NDEF messages, but not all
|
||||
* implementations will be able to read them.
|
||||
*/
|
||||
public void writeNdefMessage(NdefMessage message) throws IOException, FormatException {
|
||||
public NdefMessage[] getExtraNdefMessage() throws IOException, FormatException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get maximum NDEF message size in bytes
|
||||
*/
|
||||
public int getSize() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read/Write mode hint.
|
||||
* Provides a hint if further reads or writes are likely to succeed.
|
||||
* <p>Requires {@link android.Manifest.permission#NFC} permission.
|
||||
* @return one of NDEF_MODE
|
||||
* @throws IOException if the target is lost or connection closed
|
||||
*/
|
||||
public int getModeHint() throws IOException {
|
||||
try {
|
||||
int errorCode = mTagService.write(mTag.mServiceHandle, message);
|
||||
int result = mTagService.getModeHint(mTag.getServiceHandle());
|
||||
if (ErrorCodes.isError(result)) {
|
||||
switch (result) {
|
||||
case ErrorCodes.ERROR_IO:
|
||||
throw new IOException();
|
||||
default:
|
||||
// Should not happen
|
||||
throw new IOException();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
} catch (RemoteException e) {
|
||||
attemptDeadServiceRecovery(e);
|
||||
return NDEF_MODE_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
// Methods that require connect()
|
||||
/**
|
||||
* Overwrite the primary NDEF message
|
||||
* @throws IOException
|
||||
*/
|
||||
public void writeNdefMessage(NdefMessage msg) throws IOException, FormatException {
|
||||
try {
|
||||
int errorCode = mTagService.write(mTag.getServiceHandle(), msg);
|
||||
switch (errorCode) {
|
||||
case ErrorCodes.SUCCESS:
|
||||
break;
|
||||
@@ -140,16 +147,26 @@ public class NdefTagConnection extends RawTagConnection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to make the NDEF data in this tag read-only.
|
||||
* This method will block until the action is complete. It can be canceled
|
||||
* with {@link RawTagConnection#close}.
|
||||
* <p>Requires {@link android.Manifest.permission#NFC} permission.
|
||||
* @return true if the tag is now read-only
|
||||
* @throws IOException if the target is lost, or connection closed
|
||||
* Attempt to write extra NDEF messages.
|
||||
* Implementations may be able to write extra NDEF
|
||||
* message after the first primary message, but it is not
|
||||
* guaranteed. Even if it can be written, other implementations
|
||||
* may not be able to read NDEF messages after the primary message.
|
||||
* It is recommended to use additional NDEF records instead.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public boolean makeReadOnly() throws IOException {
|
||||
public void writeExtraNdefMessage(int i, NdefMessage msg) throws IOException, FormatException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the CC field to indicate this tag is read-only
|
||||
* @throws IOException
|
||||
*/
|
||||
public boolean makeReadonly() throws IOException {
|
||||
try {
|
||||
int errorCode = mTagService.makeReadOnly(mTag.mServiceHandle);
|
||||
int errorCode = mTagService.makeReadOnly(mTag.getServiceHandle());
|
||||
switch (errorCode) {
|
||||
case ErrorCodes.SUCCESS:
|
||||
return true;
|
||||
@@ -168,29 +185,11 @@ public class NdefTagConnection extends RawTagConnection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Read/Write mode hint.
|
||||
* Provides a hint if further reads or writes are likely to succeed.
|
||||
* <p>Requires {@link android.Manifest.permission#NFC} permission.
|
||||
* @return one of NDEF_MODE
|
||||
* @throws IOException if the target is lost or connection closed
|
||||
* Attempt to use tag specific technology to really make
|
||||
* the tag read-only
|
||||
* For NFC Forum Type 1 and 2 only.
|
||||
*/
|
||||
public int getModeHint() throws IOException {
|
||||
try {
|
||||
int result = mTagService.getModeHint(mTag.mServiceHandle);
|
||||
if (ErrorCodes.isError(result)) {
|
||||
switch (result) {
|
||||
case ErrorCodes.ERROR_IO:
|
||||
throw new IOException();
|
||||
default:
|
||||
// Should not happen
|
||||
throw new IOException();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
} catch (RemoteException e) {
|
||||
attemptDeadServiceRecovery(e);
|
||||
return NDEF_MODE_UNKNOWN;
|
||||
}
|
||||
public void makeLowLevelReadonly() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
66
core/java/android/nfc/technology/NfcA.java
Normal file
66
core/java/android/nfc/technology/NfcA.java
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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 android.nfc.technology;
|
||||
|
||||
import android.nfc.NfcAdapter;
|
||||
import android.nfc.Tag;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
|
||||
/**
|
||||
* A low-level connection to a {@link Tag} using the NFC-A technology, also known as
|
||||
* ISO1443-3A.
|
||||
*
|
||||
* <p>You can acquire this kind of connection with {@link Tag#getTechnology(int)}.
|
||||
* Use this class to send and receive data with {@link #transceive transceive()}.
|
||||
*
|
||||
* <p>Applications must implement their own protocol stack on top of
|
||||
* {@link #transceive transceive()}.
|
||||
*
|
||||
* <p class="note"><strong>Note:</strong>
|
||||
* Use of this class requires the {@link android.Manifest.permission#NFC}
|
||||
* permission.
|
||||
*/
|
||||
public final class NfcA extends BasicTagTechnology {
|
||||
/** @hide */
|
||||
public static final String EXTRA_SAK = "sak";
|
||||
/** @hide */
|
||||
public static final String EXTRA_ATQA = "atqa";
|
||||
|
||||
private short mSak;
|
||||
private byte[] mAtqa;
|
||||
|
||||
public NfcA(NfcAdapter adapter, Tag tag, Bundle extras) throws RemoteException {
|
||||
super(adapter, tag, TagTechnology.NFC_A);
|
||||
mSak = extras.getShort(EXTRA_SAK);
|
||||
mAtqa = extras.getByteArray(EXTRA_ATQA);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ATQA/SENS_RES bytes discovered at tag discovery.
|
||||
*/
|
||||
public byte[] getAtqa() {
|
||||
return mAtqa;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the SAK/SEL_RES discovered at tag discovery.
|
||||
*/
|
||||
public short getSak() {
|
||||
return mSak;
|
||||
}
|
||||
}
|
||||
55
core/java/android/nfc/technology/NfcB.java
Normal file
55
core/java/android/nfc/technology/NfcB.java
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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 android.nfc.technology;
|
||||
|
||||
import android.nfc.NfcAdapter;
|
||||
import android.nfc.Tag;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
|
||||
/**
|
||||
* A low-level connection to a {@link Tag} using the NFC-B technology, also known as
|
||||
* ISO1443-3B.
|
||||
*
|
||||
* <p>You can acquire this kind of connection with {@link Tag#getTechnology(int)}.
|
||||
* Use this class to send and receive data with {@link #transceive transceive()}.
|
||||
*
|
||||
* <p>Applications must implement their own protocol stack on top of
|
||||
* {@link #transceive transceive()}.
|
||||
*
|
||||
* <p class="note"><strong>Note:</strong>
|
||||
* Use of this class requires the {@link android.Manifest.permission#NFC}
|
||||
* permission.
|
||||
*/
|
||||
public final class NfcB extends BasicTagTechnology {
|
||||
/** @hide */
|
||||
public static final String EXTRA_ATQB = "atqb";
|
||||
|
||||
private byte[] mAtqb;
|
||||
|
||||
public NfcB(NfcAdapter adapter, Tag tag, Bundle extras)
|
||||
throws RemoteException {
|
||||
super(adapter, tag, TagTechnology.NFC_B);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ATQB/SENSB_RES bytes discovered at tag discovery.
|
||||
*/
|
||||
public byte[] getAtqb() {
|
||||
return mAtqb;
|
||||
}
|
||||
}
|
||||
63
core/java/android/nfc/technology/NfcF.java
Normal file
63
core/java/android/nfc/technology/NfcF.java
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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 android.nfc.technology;
|
||||
|
||||
import android.nfc.NfcAdapter;
|
||||
import android.nfc.Tag;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
|
||||
/**
|
||||
* A low-level connection to a {@link Tag} using the NFC-F technology, also known as
|
||||
* JIS6319-4.
|
||||
*
|
||||
* <p>You can acquire this kind of connection with {@link Tag#getTechnology(int)}.
|
||||
* Use this class to send and receive data with {@link #transceive transceive()}.
|
||||
*
|
||||
* <p>Applications must implement their own protocol stack on top of
|
||||
* {@link #transceive transceive()}.
|
||||
*
|
||||
* <p class="note"><strong>Note:</strong>
|
||||
* Use of this class requires the {@link android.Manifest.permission#NFC}
|
||||
* permission.
|
||||
*/
|
||||
public final class NfcF extends BasicTagTechnology {
|
||||
/** @hide */
|
||||
public static final String EXTRA_SC = "systemcode";
|
||||
/** @hide */
|
||||
public static final String EXTRA_PMM = "pmm";
|
||||
|
||||
private byte[] mSystemCode = null;
|
||||
private byte[] mManufacturer = null;
|
||||
|
||||
public NfcF(NfcAdapter adapter, Tag tag, Bundle extras)
|
||||
throws RemoteException {
|
||||
super(adapter, tag, TagTechnology.NFC_F);
|
||||
if (extras != null) {
|
||||
mSystemCode = extras.getByteArray(EXTRA_SC);
|
||||
mManufacturer = extras.getByteArray(EXTRA_PMM);
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] getSystemCode() {
|
||||
return mSystemCode;
|
||||
}
|
||||
|
||||
public byte[] getManufacturer() {
|
||||
return mManufacturer;
|
||||
}
|
||||
}
|
||||
43
core/java/android/nfc/technology/NfcV.java
Normal file
43
core/java/android/nfc/technology/NfcV.java
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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 android.nfc.technology;
|
||||
|
||||
import android.nfc.NfcAdapter;
|
||||
import android.nfc.Tag;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
|
||||
/**
|
||||
* A low-level connection to a {@link Tag} using the NFC-V technology, also known as
|
||||
* ISO15693.
|
||||
*
|
||||
* <p>You can acquire this kind of connection with {@link Tag#getTechnology(int)}.
|
||||
* Use this class to send and receive data with {@link #transceive transceive()}.
|
||||
*
|
||||
* <p>Applications must implement their own protocol stack on top of
|
||||
* {@link #transceive transceive()}.
|
||||
*
|
||||
* <p class="note"><strong>Note:</strong>
|
||||
* Use of this class requires the {@link android.Manifest.permission#NFC}
|
||||
* permission.
|
||||
*/
|
||||
public final class NfcV extends BasicTagTechnology {
|
||||
public NfcV(NfcAdapter adapter, Tag tag, Bundle extras)
|
||||
throws RemoteException {
|
||||
super(adapter, tag, TagTechnology.NFC_V);
|
||||
}
|
||||
}
|
||||
109
core/java/android/nfc/technology/TagTechnology.java
Normal file
109
core/java/android/nfc/technology/TagTechnology.java
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* 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 android.nfc.technology;
|
||||
|
||||
import android.nfc.Tag;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface TagTechnology {
|
||||
/**
|
||||
* This object is an instance of {@link NfcA}
|
||||
*/
|
||||
public static final int NFC_A = 1;
|
||||
|
||||
/**
|
||||
* This object is an instance of {@link NfcB}
|
||||
*/
|
||||
public static final int NFC_B = 2;
|
||||
|
||||
/**
|
||||
* This object is an instance of {@link IsoDep}
|
||||
*/
|
||||
public static final int ISO_DEP = 3;
|
||||
|
||||
/**
|
||||
* This object is an instance of {@link NfcF}
|
||||
*/
|
||||
public static final int NFC_F = 11;
|
||||
|
||||
/**
|
||||
* This object is an instance of {@link NfcV}
|
||||
*/
|
||||
public static final int NFC_V = 21;
|
||||
|
||||
/**
|
||||
* This object is an instance of {@link Ndef}
|
||||
*/
|
||||
public static final int TYPE_1 = 101;
|
||||
|
||||
/**
|
||||
* This object is an instance of {@link Ndef}
|
||||
*/
|
||||
public static final int TYPE_2 = 102;
|
||||
|
||||
/**
|
||||
* This object is an instance of {@link Ndef}
|
||||
*/
|
||||
public static final int TYPE_3 = 103;
|
||||
|
||||
/**
|
||||
* This object is an instance of {@link Ndef}
|
||||
*/
|
||||
public static final int TYPE_4 = 104;
|
||||
|
||||
/**
|
||||
* This object is an instance of {@link MifareClassic}
|
||||
*/
|
||||
public static final int MIFARE_CLASSIC = 200;
|
||||
|
||||
/**
|
||||
* A Mifare Classic tag with NDEF data
|
||||
*/
|
||||
public static final int MIFARE_CLASSIC_NDEF = 201;
|
||||
|
||||
/**
|
||||
* A Mifare Ultralight tag
|
||||
*/
|
||||
public static final int MIFARE_ULTRALIGHT = 202;
|
||||
|
||||
/**
|
||||
* A Mifare DESFire tag
|
||||
*/
|
||||
public static final int MIFARE_DESFIRE = 203;
|
||||
|
||||
/**
|
||||
* Returns the technology type for this tag connection.
|
||||
*/
|
||||
public int getTechnologyId();
|
||||
|
||||
/**
|
||||
* Get the backing tag object.
|
||||
*/
|
||||
public Tag getTag();
|
||||
|
||||
/**
|
||||
* @throws IOException
|
||||
*/
|
||||
public void connect() throws IOException;
|
||||
|
||||
/**
|
||||
* Non-blocking. Immediately causes all blocking calls
|
||||
* to throw IOException.
|
||||
*/
|
||||
public void close();
|
||||
}
|
||||
5
core/java/android/nfc/technology/package.html
Normal file
5
core/java/android/nfc/technology/package.html
Normal file
@@ -0,0 +1,5 @@
|
||||
<HTML>
|
||||
<BODY>
|
||||
{@hide}
|
||||
</BODY>
|
||||
</HTML>
|
||||
Reference in New Issue
Block a user