summaryrefslogtreecommitdiffstats
path: root/nci/src/com/android/nfc/dhimpl/NativeNfcManager.java
diff options
context:
space:
mode:
Diffstat (limited to 'nci/src/com/android/nfc/dhimpl/NativeNfcManager.java')
-rwxr-xr-xnci/src/com/android/nfc/dhimpl/NativeNfcManager.java378
1 files changed, 378 insertions, 0 deletions
diff --git a/nci/src/com/android/nfc/dhimpl/NativeNfcManager.java b/nci/src/com/android/nfc/dhimpl/NativeNfcManager.java
new file mode 100755
index 0000000..1437e5d
--- /dev/null
+++ b/nci/src/com/android/nfc/dhimpl/NativeNfcManager.java
@@ -0,0 +1,378 @@
+/*
+ * 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.android.nfc.dhimpl;
+
+import com.android.nfc.DeviceHost;
+import com.android.nfc.LlcpException;
+
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.nfc.ErrorCodes;
+import android.nfc.tech.Ndef;
+import android.nfc.tech.TagTechnology;
+import android.util.Log;
+
+/**
+ * Native interface to the NFC Manager functions
+ */
+public class NativeNfcManager implements DeviceHost {
+ private static final String TAG = "NativeNfcManager";
+ static final String PREF = "NciDeviceHost";
+
+ static final int DEFAULT_LLCP_MIU = 1980;
+ static final int DEFAULT_LLCP_RWSIZE = 2;
+
+ static final String DRIVER_NAME = "android-nci";
+
+ private static final byte[][] EE_WIPE_APDUS = {
+ {(byte)0x00, (byte)0xa4, (byte)0x04, (byte)0x00, (byte)0x00},
+ {(byte)0x00, (byte)0xa4, (byte)0x04, (byte)0x00, (byte)0x07, (byte)0xa0, (byte)0x00,
+ (byte)0x00, (byte)0x04, (byte)0x76, (byte)0x20, (byte)0x10, (byte)0x00},
+ {(byte)0x80, (byte)0xe2, (byte)0x01, (byte)0x03, (byte)0x00},
+ {(byte)0x00, (byte)0xa4, (byte)0x04, (byte)0x00, (byte)0x00},
+ {(byte)0x00, (byte)0xa4, (byte)0x04, (byte)0x00, (byte)0x07, (byte)0xa0, (byte)0x00,
+ (byte)0x00, (byte)0x04, (byte)0x76, (byte)0x30, (byte)0x30, (byte)0x00},
+ {(byte)0x80, (byte)0xb4, (byte)0x00, (byte)0x00, (byte)0x00},
+ {(byte)0x00, (byte)0xa4, (byte)0x04, (byte)0x00, (byte)0x00},
+ };
+
+ static {
+ System.loadLibrary("nfc_nci_jni");
+ }
+
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String INTERNAL_TARGET_DESELECTED_ACTION = "com.android.nfc.action.INTERNAL_TARGET_DESELECTED";
+
+ /* Native structure */
+ private int mNative;
+
+ private final DeviceHostListener mListener;
+ private final Context mContext;
+
+ public NativeNfcManager(Context context, DeviceHostListener listener) {
+ mListener = listener;
+ initializeNativeStructure();
+ mContext = context;
+ }
+
+ public native boolean initializeNativeStructure();
+
+ private native boolean doDownload();
+
+ public native int doGetLastError();
+
+ @Override
+ public void checkFirmware() {
+ }
+
+ private native boolean doInitialize();
+
+ @Override
+ public boolean initialize() {
+ SharedPreferences prefs = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = prefs.edit();
+
+ if (prefs.getBoolean(NativeNfcSecureElement.PREF_SE_WIRED, false)) {
+ try {
+ Thread.sleep (12000);
+ editor.putBoolean(NativeNfcSecureElement.PREF_SE_WIRED, false);
+ editor.apply();
+ } catch (InterruptedException e) { }
+ }
+
+ return doInitialize();
+ }
+
+ private native boolean doDeinitialize();
+
+ @Override
+ public boolean deinitialize() {
+ SharedPreferences prefs = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE);
+ SharedPreferences.Editor editor = prefs.edit();
+
+ editor.putBoolean(NativeNfcSecureElement.PREF_SE_WIRED, false);
+ editor.apply();
+
+ return doDeinitialize();
+ }
+
+ @Override
+ public String getName() {
+ return DRIVER_NAME;
+ }
+
+ @Override
+ public native void enableDiscovery();
+
+ @Override
+ public native void disableDiscovery();
+
+ @Override
+ public native int[] doGetSecureElementList();
+
+ @Override
+ public native void doSelectSecureElement();
+
+ @Override
+ public native void doDeselectSecureElement();
+
+
+ private native NativeLlcpConnectionlessSocket doCreateLlcpConnectionlessSocket(int nSap,
+ String sn);
+
+ @Override
+ public LlcpConnectionlessSocket createLlcpConnectionlessSocket(int nSap, String sn)
+ throws LlcpException {
+ LlcpConnectionlessSocket socket = doCreateLlcpConnectionlessSocket(nSap, sn);
+ if (socket != null) {
+ return socket;
+ } else {
+ /* Get Error Status */
+ int error = doGetLastError();
+
+ Log.d(TAG, "failed to create llcp socket: " + ErrorCodes.asString(error));
+
+ switch (error) {
+ case ErrorCodes.ERROR_BUFFER_TO_SMALL:
+ case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES:
+ throw new LlcpException(error);
+ default:
+ throw new LlcpException(ErrorCodes.ERROR_SOCKET_CREATION);
+ }
+ }
+ }
+
+ private native NativeLlcpServiceSocket doCreateLlcpServiceSocket(int nSap, String sn, int miu,
+ int rw, int linearBufferLength);
+ @Override
+ public LlcpServerSocket createLlcpServerSocket(int nSap, String sn, int miu,
+ int rw, int linearBufferLength) throws LlcpException {
+ LlcpServerSocket socket = doCreateLlcpServiceSocket(nSap, sn, miu, rw, linearBufferLength);
+ if (socket != null) {
+ return socket;
+ } else {
+ /* Get Error Status */
+ int error = doGetLastError();
+
+ Log.d(TAG, "failed to create llcp socket: " + ErrorCodes.asString(error));
+
+ switch (error) {
+ case ErrorCodes.ERROR_BUFFER_TO_SMALL:
+ case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES:
+ throw new LlcpException(error);
+ default:
+ throw new LlcpException(ErrorCodes.ERROR_SOCKET_CREATION);
+ }
+ }
+ }
+
+ private native NativeLlcpSocket doCreateLlcpSocket(int sap, int miu, int rw,
+ int linearBufferLength);
+ @Override
+ public LlcpSocket createLlcpSocket(int sap, int miu, int rw,
+ int linearBufferLength) throws LlcpException {
+ LlcpSocket socket = doCreateLlcpSocket(sap, miu, rw, linearBufferLength);
+ if (socket != null) {
+ return socket;
+ } else {
+ /* Get Error Status */
+ int error = doGetLastError();
+
+ Log.d(TAG, "failed to create llcp socket: " + ErrorCodes.asString(error));
+
+ switch (error) {
+ case ErrorCodes.ERROR_BUFFER_TO_SMALL:
+ case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES:
+ throw new LlcpException(error);
+ default:
+ throw new LlcpException(ErrorCodes.ERROR_SOCKET_CREATION);
+ }
+ }
+ }
+
+ @Override
+ public native boolean doCheckLlcp();
+
+ @Override
+ public native boolean doActivateLlcp();
+
+ private native void doResetTimeouts();
+
+ @Override
+ public void resetTimeouts() {
+ doResetTimeouts();
+ }
+
+ @Override
+ public native void doAbort();
+
+ private native boolean doSetTimeout(int tech, int timeout);
+ @Override
+ public boolean setTimeout(int tech, int timeout) {
+ return doSetTimeout(tech, timeout);
+ }
+
+ private native int doGetTimeout(int tech);
+ @Override
+ public int getTimeout(int tech) {
+ return doGetTimeout(tech);
+ }
+
+
+ @Override
+ public boolean canMakeReadOnly(int ndefType) {
+ return (ndefType == Ndef.TYPE_1 || ndefType == Ndef.TYPE_2);
+ }
+
+ @Override
+ public int getMaxTransceiveLength(int technology) {
+ switch (technology) {
+ case (TagTechnology.NFC_A):
+ case (TagTechnology.MIFARE_CLASSIC):
+ case (TagTechnology.MIFARE_ULTRALIGHT):
+ return 253; // PN544 RF buffer = 255 bytes, subtract two for CRC
+ case (TagTechnology.NFC_B):
+ /////////////////////////////////////////////////////////////////
+ // Broadcom: Since BCM2079x supports this, set NfcB max size.
+ //return 0; // PN544 does not support transceive of raw NfcB
+ return 253; // PN544 does not support transceive of raw NfcB
+ case (TagTechnology.NFC_V):
+ return 253; // PN544 RF buffer = 255 bytes, subtract two for CRC
+ case (TagTechnology.ISO_DEP):
+ /* The maximum length of a normal IsoDep frame consists of:
+ * CLA, INS, P1, P2, LC, LE + 255 payload bytes = 261 bytes
+ * such a frame is supported. Extended length frames however
+ * are not supported.
+ */
+ return 261; // Will be automatically split in two frames on the RF layer
+ case (TagTechnology.NFC_F):
+ return 252; // PN544 RF buffer = 255 bytes, subtract one for SoD, two for CRC
+ default:
+ return 0;
+ }
+
+ }
+
+ private native void doSetP2pInitiatorModes(int modes);
+ @Override
+ public void setP2pInitiatorModes(int modes) {
+ doSetP2pInitiatorModes(modes);
+ }
+
+ private native void doSetP2pTargetModes(int modes);
+ @Override
+ public void setP2pTargetModes(int modes) {
+ doSetP2pTargetModes(modes);
+ }
+ @Override
+ public boolean getExtendedLengthApdusSupported() {
+ // TODO check BCM support
+ return false;
+ }
+
+ @Override
+ public boolean enablePN544Quirks() {
+ return false;
+ }
+
+ @Override
+ public byte[][] getWipeApdus() {
+ return EE_WIPE_APDUS;
+ }
+
+ @Override
+ public int getDefaultLlcpMiu() {
+ return DEFAULT_LLCP_MIU;
+ }
+
+ @Override
+ public int getDefaultLlcpRwSize() {
+ return DEFAULT_LLCP_RWSIZE;
+ }
+
+ private native String doDump();
+ @Override
+ public String dump() {
+ return doDump();
+ }
+
+ /**
+ * Notifies Ndef Message (TODO: rename into notifyTargetDiscovered)
+ */
+ private void notifyNdefMessageListeners(NativeNfcTag tag) {
+ mListener.onRemoteEndpointDiscovered(tag);
+ }
+
+ /**
+ * Notifies transaction
+ */
+ private void notifyTargetDeselected() {
+ mListener.onCardEmulationDeselected();
+ }
+
+ /**
+ * Notifies transaction
+ */
+ private void notifyTransactionListeners(byte[] aid) {
+ mListener.onCardEmulationAidSelected(aid);
+ }
+
+ /**
+ * Notifies P2P Device detected, to activate LLCP link
+ */
+ private void notifyLlcpLinkActivation(NativeP2pDevice device) {
+ mListener.onLlcpLinkActivated(device);
+ }
+
+ /**
+ * Notifies P2P Device detected, to activate LLCP link
+ */
+ private void notifyLlcpLinkDeactivated(NativeP2pDevice device) {
+ mListener.onLlcpLinkDeactivated(device);
+ }
+
+ private void notifySeFieldActivated() {
+ mListener.onRemoteFieldActivated();
+ }
+
+ private void notifySeFieldDeactivated() {
+ mListener.onRemoteFieldDeactivated();
+ }
+
+ private void notifySeListenActivated() {
+ mListener.onSeListenActivated();
+ }
+
+ private void notifySeListenDeactivated() {
+ mListener.onSeListenDeactivated();
+ }
+
+ private void notifySeApduReceived(byte[] apdu) {
+ mListener.onSeApduReceived(apdu);
+ }
+
+ private void notifySeEmvCardRemoval() {
+ mListener.onSeEmvCardRemoval();
+ }
+
+ private void notifySeMifareAccess(byte[] block) {
+ mListener.onSeMifareAccess(block);
+ }
+
+}