diff options
author | Martijn Coenen <maco@google.com> | 2012-07-20 15:09:37 -0400 |
---|---|---|
committer | Martijn Coenen <maco@google.com> | 2012-07-24 20:29:18 -0700 |
commit | 26f6049196acaa9768ba6bdef343216ea878a4c1 (patch) | |
tree | 6dbe4f38ed6d175bb4cdc1c3c8fc8f2810302f50 /src | |
parent | 63cccc4b5096fd9cbcb08410e69f7932375b4bc6 (diff) | |
download | packages_apps_nfc-26f6049196acaa9768ba6bdef343216ea878a4c1.zip packages_apps_nfc-26f6049196acaa9768ba6bdef343216ea878a4c1.tar.gz packages_apps_nfc-26f6049196acaa9768ba6bdef343216ea878a4c1.tar.bz2 |
Move NXP JNI and DeviceHost implementation into separate dir.
Preparation for the new NCI stack. The idea is to
build either the NXP or the NCI stack, triggered
by a makefile switch. To that end, move the
DeviceHost and JNI implementations in their own
directory, so we can build them only if needed.
Change-Id: Ibb6aeb11f0bb887e153fd457860b1ad0e39e7933
Diffstat (limited to 'src')
-rwxr-xr-x | src/com/android/nfc/NfcService.java | 4 | ||||
-rwxr-xr-x | src/com/android/nfc/nxp/NativeLlcpConnectionlessSocket.java | 78 | ||||
-rwxr-xr-x | src/com/android/nfc/nxp/NativeLlcpServiceSocket.java | 53 | ||||
-rwxr-xr-x | src/com/android/nfc/nxp/NativeLlcpSocket.java | 99 | ||||
-rwxr-xr-x | src/com/android/nfc/nxp/NativeNfcManager.java | 373 | ||||
-rwxr-xr-x | src/com/android/nfc/nxp/NativeNfcSecureElement.java | 67 | ||||
-rwxr-xr-x | src/com/android/nfc/nxp/NativeNfcTag.java | 803 | ||||
-rwxr-xr-x | src/com/android/nfc/nxp/NativeP2pDevice.java | 77 |
8 files changed, 2 insertions, 1552 deletions
diff --git a/src/com/android/nfc/NfcService.java b/src/com/android/nfc/NfcService.java index 602b25d..3e7a6b5 100755 --- a/src/com/android/nfc/NfcService.java +++ b/src/com/android/nfc/NfcService.java @@ -23,8 +23,8 @@ import com.android.nfc.DeviceHost.LlcpSocket; import com.android.nfc.DeviceHost.NfcDepEndpoint; import com.android.nfc.DeviceHost.TagEndpoint; import com.android.nfc.handover.HandoverManager; -import com.android.nfc.nxp.NativeNfcManager; -import com.android.nfc.nxp.NativeNfcSecureElement; +import com.android.nfc.dhimpl.NativeNfcManager; +import com.android.nfc.dhimpl.NativeNfcSecureElement; import android.app.Application; import android.app.KeyguardManager; diff --git a/src/com/android/nfc/nxp/NativeLlcpConnectionlessSocket.java b/src/com/android/nfc/nxp/NativeLlcpConnectionlessSocket.java deleted file mode 100755 index c9d3b5d..0000000 --- a/src/com/android/nfc/nxp/NativeLlcpConnectionlessSocket.java +++ /dev/null @@ -1,78 +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.android.nfc.nxp; - -import com.android.nfc.DeviceHost; -import com.android.nfc.LlcpPacket; - -import java.io.IOException; - -/** - * LlcpConnectionlessSocket represents a LLCP Connectionless object to be used - * in a connectionless communication - */ -public class NativeLlcpConnectionlessSocket implements DeviceHost.LlcpConnectionlessSocket { - - private int mHandle; - private int mSap; - private int mLinkMiu; - - public NativeLlcpConnectionlessSocket() { } - - public native boolean doSendTo(int sap, byte[] data); - - public native LlcpPacket doReceiveFrom(int linkMiu); - - public native boolean doClose(); - - @Override - public int getLinkMiu(){ - return mLinkMiu; - } - - @Override - public int getSap(){ - return mSap; - } - - @Override - public void send(int sap, byte[] data) throws IOException { - if (!doSendTo(sap, data)) { - throw new IOException(); - } - } - - @Override - public LlcpPacket receive() throws IOException { - LlcpPacket packet = doReceiveFrom(mLinkMiu); - if (packet == null) { - throw new IOException(); - } - return packet; - } - - public int getHandle(){ - return mHandle; - } - - @Override - public void close() throws IOException { - if (!doClose()) { - throw new IOException(); - } - } -} diff --git a/src/com/android/nfc/nxp/NativeLlcpServiceSocket.java b/src/com/android/nfc/nxp/NativeLlcpServiceSocket.java deleted file mode 100755 index 531afd8..0000000 --- a/src/com/android/nfc/nxp/NativeLlcpServiceSocket.java +++ /dev/null @@ -1,53 +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.android.nfc.nxp; - -import com.android.nfc.DeviceHost; -import com.android.nfc.DeviceHost.LlcpSocket; - -import java.io.IOException; - -/** - * LlcpServiceSocket represents a LLCP Service to be used in a - * Connection-oriented communication - */ -public class NativeLlcpServiceSocket implements DeviceHost.LlcpServerSocket { - private int mHandle; - private int mLocalMiu; - private int mLocalRw; - private int mLocalLinearBufferLength; - private int mSap; - private String mServiceName; - - public NativeLlcpServiceSocket(){ } - - private native NativeLlcpSocket doAccept(int miu, int rw, int linearBufferLength); - @Override - public LlcpSocket accept() throws IOException { - LlcpSocket socket = doAccept(mLocalMiu, mLocalRw, mLocalLinearBufferLength); - if (socket == null) throw new IOException(); - return socket; - } - - private native boolean doClose(); - @Override - public void close() throws IOException { - if (!doClose()) { - throw new IOException(); - } - } -} diff --git a/src/com/android/nfc/nxp/NativeLlcpSocket.java b/src/com/android/nfc/nxp/NativeLlcpSocket.java deleted file mode 100755 index a337d35..0000000 --- a/src/com/android/nfc/nxp/NativeLlcpSocket.java +++ /dev/null @@ -1,99 +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.android.nfc.nxp; - -import com.android.nfc.DeviceHost; - -import java.io.IOException; - -/** - * LlcpClientSocket represents a LLCP Connection-Oriented client to be used in a - * connection-oriented communication - */ -public class NativeLlcpSocket implements DeviceHost.LlcpSocket { - private int mHandle; - private int mSap; - private int mLocalMiu; - private int mLocalRw; - - public NativeLlcpSocket(){ } - - private native boolean doConnect(int nSap); - @Override - public void connectToSap(int sap) throws IOException { - if (!doConnect(sap)) { - throw new IOException(); - } - } - - private native boolean doConnectBy(String sn); - @Override - public void connectToService(String serviceName) throws IOException { - if (!doConnectBy(serviceName)) { - throw new IOException(); - } - } - - private native boolean doClose(); - @Override - public void close() throws IOException { - if (!doClose()) { - throw new IOException(); - } - } - - private native boolean doSend(byte[] data); - @Override - public void send(byte[] data) throws IOException { - if (!doSend(data)) { - throw new IOException(); - } - } - - private native int doReceive(byte[] recvBuff); - @Override - public int receive(byte[] recvBuff) throws IOException { - int receiveLength = doReceive(recvBuff); - if (receiveLength == -1) { - throw new IOException(); - } - return receiveLength; - } - - private native int doGetRemoteSocketMiu(); - @Override - public int getRemoteMiu() { return doGetRemoteSocketMiu(); } - - private native int doGetRemoteSocketRw(); - @Override - public int getRemoteRw() { return doGetRemoteSocketRw(); } - - @Override - public int getLocalSap(){ - return mSap; - } - - @Override - public int getLocalMiu(){ - return mLocalMiu; - } - - @Override - public int getLocalRw(){ - return mLocalRw; - } -} diff --git a/src/com/android/nfc/nxp/NativeNfcManager.java b/src/com/android/nfc/nxp/NativeNfcManager.java deleted file mode 100755 index 4bd8c24..0000000 --- a/src/com/android/nfc/nxp/NativeNfcManager.java +++ /dev/null @@ -1,373 +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.android.nfc.nxp; - -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; - -import java.io.File; - -/** - * Native interface to the NFC Manager functions - */ -public class NativeNfcManager implements DeviceHost { - private static final String TAG = "NativeNfcManager"; - - private static final String NFC_CONTROLLER_FIRMWARE_FILE_NAME = "/vendor/firmware/libpn544_fw.so"; - - static final String PREF = "NxpDeviceHost"; - - private static final String PREF_FIRMWARE_MODTIME = "firmware_modtime"; - private static final long FIRMWARE_MODTIME_DEFAULT = -1; - - static { - System.loadLibrary("nfc_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() { - // Check that the NFC controller firmware is up to date. This - // ensures that firmware updates are applied in a timely fashion, - // and makes it much less likely that the user will have to wait - // for a firmware download when they enable NFC in the settings - // app. Firmware download can take some time, so this should be - // run in a separate thread. - - // check the timestamp of the firmware file - File firmwareFile; - int nbRetry = 0; - try { - firmwareFile = new File(NFC_CONTROLLER_FIRMWARE_FILE_NAME); - } catch(NullPointerException npe) { - Log.e(TAG,"path to firmware file was null"); - return; - } - - long modtime = firmwareFile.lastModified(); - - SharedPreferences prefs = mContext.getSharedPreferences(PREF, Context.MODE_PRIVATE); - long prev_fw_modtime = prefs.getLong(PREF_FIRMWARE_MODTIME, FIRMWARE_MODTIME_DEFAULT); - Log.d(TAG,"prev modtime: " + prev_fw_modtime); - Log.d(TAG,"new modtime: " + modtime); - if (prev_fw_modtime == modtime) { - return; - } - - // FW download. - while(nbRetry < 5) { - Log.d(TAG,"Perform Download"); - if(doDownload()) { - Log.d(TAG,"Download Success"); - // Now that we've finished updating the firmware, save the new modtime. - prefs.edit().putLong(PREF_FIRMWARE_MODTIME, modtime).apply(); - break; - } else { - Log.d(TAG,"Download Failed"); - nbRetry++; - } - } - } - - 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 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 || - ndefType == Ndef.TYPE_MIFARE_CLASSIC); - } - - @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): - return 0; // 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); - } - - public boolean getExtendedLengthApdusSupported() { - // Not supported on the PN544 - return false; - } - - 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 notifySeApduReceived(byte[] apdu) { - mListener.onSeApduReceived(apdu); - } - - private void notifySeEmvCardRemoval() { - mListener.onSeEmvCardRemoval(); - } - - private void notifySeMifareAccess(byte[] block) { - mListener.onSeMifareAccess(block); - } -} diff --git a/src/com/android/nfc/nxp/NativeNfcSecureElement.java b/src/com/android/nfc/nxp/NativeNfcSecureElement.java deleted file mode 100755 index 88f9b9d..0000000 --- a/src/com/android/nfc/nxp/NativeNfcSecureElement.java +++ /dev/null @@ -1,67 +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.android.nfc.nxp; - -import android.content.Context; -import android.content.SharedPreferences; - - -/** - * Native interface to the NFC Secure Element functions - * - * {@hide} - */ -public class NativeNfcSecureElement { - - static final String PREF_SE_WIRED = "se_wired"; - - private final Context mContext; - - SharedPreferences mPrefs; - SharedPreferences.Editor mPrefsEditor; - - public NativeNfcSecureElement(Context context) { - mContext = context; - - mPrefs = mContext.getSharedPreferences(NativeNfcManager.PREF, Context.MODE_PRIVATE); - mPrefsEditor = mPrefs.edit(); - } - - private native int doNativeOpenSecureElementConnection(); - - public int doOpenSecureElementConnection() { - mPrefsEditor.putBoolean(PREF_SE_WIRED, true); - mPrefsEditor.apply(); - - return doNativeOpenSecureElementConnection(); - } - - private native boolean doNativeDisconnectSecureElementConnection(int handle); - - public boolean doDisconnect(int handle) { - mPrefsEditor.putBoolean(PREF_SE_WIRED, false); - mPrefsEditor.apply(); - - return doNativeDisconnectSecureElementConnection(handle); - } - - public native byte[] doTransceive(int handle, byte[] data); - - public native int[] doGetTechList(int handle); - - public native byte [] doGetUid(int handle); -} diff --git a/src/com/android/nfc/nxp/NativeNfcTag.java b/src/com/android/nfc/nxp/NativeNfcTag.java deleted file mode 100755 index 8996dfb..0000000 --- a/src/com/android/nfc/nxp/NativeNfcTag.java +++ /dev/null @@ -1,803 +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.android.nfc.nxp; - -import com.android.nfc.DeviceHost.TagEndpoint; - -import android.nfc.FormatException; -import android.nfc.NdefMessage; -import android.nfc.tech.IsoDep; -import android.nfc.tech.MifareClassic; -import android.nfc.tech.MifareUltralight; -import android.nfc.tech.Ndef; -import android.nfc.tech.NfcA; -import android.nfc.tech.NfcB; -import android.nfc.tech.NfcF; -import android.nfc.tech.NfcV; -import android.nfc.tech.TagTechnology; -import android.os.Bundle; -import android.util.Log; - -/** - * Native interface to the NFC tag functions - */ -public class NativeNfcTag implements TagEndpoint { - static final boolean DBG = false; - - static final int STATUS_CODE_TARGET_LOST = 146; - - private int[] mTechList; - private int[] mTechHandles; - private int[] mTechLibNfcTypes; - private Bundle[] mTechExtras; - private byte[][] mTechPollBytes; - private byte[][] mTechActBytes; - private byte[] mUid; - - // mConnectedHandle stores the *real* libnfc handle - // that we're connected to. - private int mConnectedHandle; - - // mConnectedTechIndex stores to which technology - // the upper layer stack is connected. Note that - // we may be connected to a libnfchandle without being - // connected to a technology - technology changes - // may occur runtime, whereas the underlying handle - // could stay present. Usually all technologies are on the - // same handle, with the exception of multi-protocol - // tags. - private int mConnectedTechIndex; // Index in mTechHandles - - private final String TAG = "NativeNfcTag"; - - private boolean mIsPresent; // Whether the tag is known to be still present - - private PresenceCheckWatchdog mWatchdog; - class PresenceCheckWatchdog extends Thread { - - private int watchdogTimeout = 125; - - private boolean isPresent = true; - private boolean isStopped = false; - private boolean isPaused = false; - private boolean doCheck = true; - - public synchronized void pause() { - isPaused = true; - doCheck = false; - this.notifyAll(); - } - - public synchronized void doResume() { - isPaused = false; - // We don't want to resume presence checking immediately, - // but go through at least one more wait period. - doCheck = false; - this.notifyAll(); - } - - public synchronized void end() { - isStopped = true; - doCheck = false; - this.notifyAll(); - } - - public synchronized void setTimeout(int timeout) { - watchdogTimeout = timeout; - doCheck = false; // Do it only after we have waited "timeout" ms again - this.notifyAll(); - } - - @Override - public synchronized void run() { - if (DBG) Log.d(TAG, "Starting background presence check"); - while (isPresent && !isStopped) { - try { - if (!isPaused) { - doCheck = true; - } - this.wait(watchdogTimeout); - if (doCheck) { - isPresent = doPresenceCheck(); - } else { - // 1) We are paused, waiting for unpause - // 2) We just unpaused, do pres check in next iteration - // (after watchdogTimeout ms sleep) - // 3) We just set the timeout, wait for this timeout - // to expire once first. - // 4) We just stopped, exit loop anyway - } - } catch (InterruptedException e) { - // Activity detected, loop - } - } - mIsPresent = false; - // Restart the polling loop - - Log.d(TAG, "Tag lost, restarting polling loop"); - doDisconnect(); - if (DBG) Log.d(TAG, "Stopping background presence check"); - } - } - - private native int doConnect(int handle); - public synchronized int connectWithStatus(int technology) { - if (mWatchdog != null) { - mWatchdog.pause(); - } - int status = -1; - for (int i = 0; i < mTechList.length; i++) { - if (mTechList[i] == technology) { - // Get the handle and connect, if not already connected - if (mConnectedHandle != mTechHandles[i]) { - // We're not yet connected to this handle, there are - // a few scenario's here: - // 1) We are not connected to anything yet - allow - // 2) We are connected to a technology which has - // a different handle (multi-protocol tag); we support - // switching to that. - if (mConnectedHandle == -1) { - // Not connected yet - status = doConnect(mTechHandles[i]); - } else { - // Connect to a tech with a different handle - status = reconnectWithStatus(mTechHandles[i]); - } - if (status == 0) { - mConnectedHandle = mTechHandles[i]; - mConnectedTechIndex = i; - } - } else { - // 1) We are connected to a technology which has the same - // handle; we do not support connecting at a different - // level (libnfc auto-activates to the max level on - // any handle). - // 2) We are connecting to the ndef technology - always - // allowed. - if ((technology == TagTechnology.NDEF) || - (technology == TagTechnology.NDEF_FORMATABLE)) { - status = 0; - } else { - if ((technology != TagTechnology.ISO_DEP) && - (hasTechOnHandle(TagTechnology.ISO_DEP, mTechHandles[i]))) { - // Don't allow to connect a -4 tag at a different level - // than IsoDep, as this is not supported by - // libNFC. - status = -1; - } else { - status = 0; - } - } - if (status == 0) { - mConnectedTechIndex = i; - // Handle was already identical - } - } - break; - } - } - if (mWatchdog != null) { - mWatchdog.doResume(); - } - return status; - } - @Override - public synchronized boolean connect(int technology) { - return connectWithStatus(technology) == 0; - } - - @Override - public synchronized void startPresenceChecking() { - // Once we start presence checking, we allow the upper layers - // to know the tag is in the field. - mIsPresent = true; - if (mWatchdog == null) { - mWatchdog = new PresenceCheckWatchdog(); - mWatchdog.start(); - } - } - - @Override - public synchronized boolean isPresent() { - // Returns whether the tag is still in the field to the best - // of our knowledge. - return mIsPresent; - } - native boolean doDisconnect(); - @Override - public synchronized boolean disconnect() { - boolean result = false; - - mIsPresent = false; - if (mWatchdog != null) { - // Watchdog has already disconnected or will do it - mWatchdog.end(); - try { - mWatchdog.join(); - } catch (InterruptedException e) { - // Should never happen. - } - mWatchdog = null; - result = true; - } else { - result = doDisconnect(); - } - - mConnectedTechIndex = -1; - mConnectedHandle = -1; - return result; - } - - native int doReconnect(); - public synchronized int reconnectWithStatus() { - if (mWatchdog != null) { - mWatchdog.pause(); - } - int status = doReconnect(); - if (mWatchdog != null) { - mWatchdog.doResume(); - } - return status; - } - @Override - public synchronized boolean reconnect() { - return reconnectWithStatus() == 0; - } - - native int doHandleReconnect(int handle); - public synchronized int reconnectWithStatus(int handle) { - if (mWatchdog != null) { - mWatchdog.pause(); - } - int status = doHandleReconnect(handle); - if (mWatchdog != null) { - mWatchdog.doResume(); - } - return status; - } - - private native byte[] doTransceive(byte[] data, boolean raw, int[] returnCode); - @Override - public synchronized byte[] transceive(byte[] data, boolean raw, int[] returnCode) { - if (mWatchdog != null) { - mWatchdog.pause(); - } - byte[] result = doTransceive(data, raw, returnCode); - if (mWatchdog != null) { - mWatchdog.doResume(); - } - return result; - } - - private native int doCheckNdef(int[] ndefinfo); - private synchronized int checkNdefWithStatus(int[] ndefinfo) { - if (mWatchdog != null) { - mWatchdog.pause(); - } - int status = doCheckNdef(ndefinfo); - if (mWatchdog != null) { - mWatchdog.doResume(); - } - return status; - } - @Override - public synchronized boolean checkNdef(int[] ndefinfo) { - return checkNdefWithStatus(ndefinfo) == 0; - } - - private native byte[] doRead(); - @Override - public synchronized byte[] readNdef() { - if (mWatchdog != null) { - mWatchdog.pause(); - } - byte[] result = doRead(); - if (mWatchdog != null) { - mWatchdog.doResume(); - } - return result; - } - - private native boolean doWrite(byte[] buf); - @Override - public synchronized boolean writeNdef(byte[] buf) { - if (mWatchdog != null) { - mWatchdog.pause(); - } - boolean result = doWrite(buf); - if (mWatchdog != null) { - mWatchdog.doResume(); - } - return result; - } - - native boolean doPresenceCheck(); - @Override - public synchronized boolean presenceCheck() { - if (mWatchdog != null) { - mWatchdog.pause(); - } - boolean result = doPresenceCheck(); - if (mWatchdog != null) { - mWatchdog.doResume(); - } - return result; - } - - native boolean doNdefFormat(byte[] key); - @Override - public synchronized boolean formatNdef(byte[] key) { - if (mWatchdog != null) { - mWatchdog.pause(); - } - boolean result = doNdefFormat(key); - if (mWatchdog != null) { - mWatchdog.doResume(); - } - return result; - } - - native boolean doMakeReadonly(byte[] key); - @Override - public synchronized boolean makeReadOnly() { - if (mWatchdog != null) { - mWatchdog.pause(); - } - boolean result; - if (hasTech(TagTechnology.MIFARE_CLASSIC)) { - result = doMakeReadonly(MifareClassic.KEY_DEFAULT); - } else { - // No key needed for other technologies - result = doMakeReadonly(new byte[] {}); - } - if (mWatchdog != null) { - mWatchdog.doResume(); - } - return result; - } - - native boolean doIsIsoDepNdefFormatable(byte[] poll, byte[] act); - @Override - public synchronized boolean isNdefFormatable() { - if (hasTech(TagTechnology.MIFARE_CLASSIC) || hasTech(TagTechnology.MIFARE_ULTRALIGHT)) { - // These are always formatable - return true; - } - if (hasTech(TagTechnology.NFC_V)) { - // Currently libnfc only formats NXP NFC-V tags - if (mUid[5] >= 1 && mUid[5] <= 3 && mUid[6] == 0x04) { - return true; - } else { - return false; - } - } - // For ISO-DEP, call native code to determine at lower level if format - // is possible. It will need NFC-A poll/activation time bytes for this. - if (hasTech(TagTechnology.ISO_DEP)) { - int nfcaTechIndex = getTechIndex(TagTechnology.NFC_A); - if (nfcaTechIndex != -1) { - return doIsIsoDepNdefFormatable(mTechPollBytes[nfcaTechIndex], - mTechActBytes[nfcaTechIndex]); - } else { - return false; - } - } else { - // Formatting not supported by libNFC - return false; - } - } - - @Override - public int getHandle() { - // This is just a handle for the clients; it can simply use the first - // technology handle we have. - if (mTechHandles.length > 0) { - return mTechHandles[0]; - } else { - return 0; - } - } - - @Override - public byte[] getUid() { - return mUid; - } - - @Override - public int[] getTechList() { - return mTechList; - } - - private int getConnectedHandle() { - return mConnectedHandle; - } - - private int getConnectedLibNfcType() { - if (mConnectedTechIndex != -1 && mConnectedTechIndex < mTechLibNfcTypes.length) { - return mTechLibNfcTypes[mConnectedTechIndex]; - } else { - return 0; - } - } - - @Override - public int getConnectedTechnology() { - if (mConnectedTechIndex != -1 && mConnectedTechIndex < mTechList.length) { - return mTechList[mConnectedTechIndex]; - } else { - return 0; - } - } - native int doGetNdefType(int libnfctype, int javatype); - private int getNdefType(int libnfctype, int javatype) { - return doGetNdefType(libnfctype, javatype); - } - - private void addTechnology(int tech, int handle, int libnfctype) { - int[] mNewTechList = new int[mTechList.length + 1]; - System.arraycopy(mTechList, 0, mNewTechList, 0, mTechList.length); - mNewTechList[mTechList.length] = tech; - mTechList = mNewTechList; - - int[] mNewHandleList = new int[mTechHandles.length + 1]; - System.arraycopy(mTechHandles, 0, mNewHandleList, 0, mTechHandles.length); - mNewHandleList[mTechHandles.length] = handle; - mTechHandles = mNewHandleList; - - int[] mNewTypeList = new int[mTechLibNfcTypes.length + 1]; - System.arraycopy(mTechLibNfcTypes, 0, mNewTypeList, 0, mTechLibNfcTypes.length); - mNewTypeList[mTechLibNfcTypes.length] = libnfctype; - mTechLibNfcTypes = mNewTypeList; - } - - @Override - public void removeTechnology(int tech) { - synchronized (this) { - int techIndex = getTechIndex(tech); - if (techIndex != -1) { - int[] mNewTechList = new int[mTechList.length - 1]; - System.arraycopy(mTechList, 0, mNewTechList, 0, techIndex); - System.arraycopy(mTechList, techIndex + 1, mNewTechList, techIndex, - mTechList.length - techIndex - 1); - mTechList = mNewTechList; - - int[] mNewHandleList = new int[mTechHandles.length - 1]; - System.arraycopy(mTechHandles, 0, mNewHandleList, 0, techIndex); - System.arraycopy(mTechHandles, techIndex + 1, mNewTechList, techIndex, - mTechHandles.length - techIndex - 1); - mTechHandles = mNewHandleList; - - int[] mNewTypeList = new int[mTechLibNfcTypes.length - 1]; - System.arraycopy(mTechLibNfcTypes, 0, mNewTypeList, 0, techIndex); - System.arraycopy(mTechLibNfcTypes, techIndex + 1, mNewTypeList, techIndex, - mTechLibNfcTypes.length - techIndex - 1); - mTechLibNfcTypes = mNewTypeList; - } - } - } - - public void addNdefFormatableTechnology(int handle, int libnfcType) { - synchronized (this) { - addTechnology(TagTechnology.NDEF_FORMATABLE, handle, libnfcType); - } - } - - // This method exists to "patch in" the ndef technologies, - // which is done inside Java instead of the native JNI code. - // To not create some nasty dependencies on the order on which things - // are called (most notably getTechExtras()), it needs some additional - // checking. - public void addNdefTechnology(NdefMessage msg, int handle, int libnfcType, - int javaType, int maxLength, int cardState) { - synchronized (this) { - addTechnology(TagTechnology.NDEF, handle, libnfcType); - - Bundle extras = new Bundle(); - extras.putParcelable(Ndef.EXTRA_NDEF_MSG, msg); - extras.putInt(Ndef.EXTRA_NDEF_MAXLENGTH, maxLength); - extras.putInt(Ndef.EXTRA_NDEF_CARDSTATE, cardState); - extras.putInt(Ndef.EXTRA_NDEF_TYPE, getNdefType(libnfcType, javaType)); - - if (mTechExtras == null) { - // This will build the tech extra's for the first time, - // including a NULL ref for the NDEF tech we generated above. - Bundle[] builtTechExtras = getTechExtras(); - builtTechExtras[builtTechExtras.length - 1] = extras; - } - else { - // Tech extras were built before, patch the NDEF one in - Bundle[] oldTechExtras = getTechExtras(); - Bundle[] newTechExtras = new Bundle[oldTechExtras.length + 1]; - System.arraycopy(oldTechExtras, 0, newTechExtras, 0, oldTechExtras.length); - newTechExtras[oldTechExtras.length] = extras; - mTechExtras = newTechExtras; - } - - - } - } - - private int getTechIndex(int tech) { - int techIndex = -1; - for (int i = 0; i < mTechList.length; i++) { - if (mTechList[i] == tech) { - techIndex = i; - break; - } - } - return techIndex; - } - - private boolean hasTech(int tech) { - boolean hasTech = false; - for (int i = 0; i < mTechList.length; i++) { - if (mTechList[i] == tech) { - hasTech = true; - break; - } - } - return hasTech; - } - - private boolean hasTechOnHandle(int tech, int handle) { - boolean hasTech = false; - for (int i = 0; i < mTechList.length; i++) { - if (mTechList[i] == tech && mTechHandles[i] == handle) { - hasTech = true; - break; - } - } - return hasTech; - - } - - private boolean isUltralightC() { - /* Make a best-effort attempt at classifying ULTRALIGHT - * vs ULTRALIGHT-C (based on NXP's public AN1303). - * The memory layout is as follows: - * Page # BYTE1 BYTE2 BYTE3 BYTE4 - * 2 INT1 INT2 LOCK LOCK - * 3 OTP OTP OTP OTP (NDEF CC if NDEF-formatted) - * 4 DATA DATA DATA DATA (version info if factory-state) - * - * Read four blocks from page 2, which will get us both - * the lock page, the OTP page and the version info. - */ - boolean isUltralightC = false; - byte[] readCmd = { 0x30, 0x02 }; - int[] retCode = new int[2]; - byte[] respData = transceive(readCmd, false, retCode); - if (respData != null && respData.length == 16) { - // Check the lock bits (last 2 bytes in page2) - // and the OTP bytes (entire page 3) - if (respData[2] == 0 && respData[3] == 0 && respData[4] == 0 && - respData[5] == 0 && respData[6] == 0 && respData[7] == 0) { - // Very likely to be a blank card, look at version info - // in page 4. - if ((respData[8] == (byte)0x02) && respData[9] == (byte)0x00) { - // This is Ultralight-C - isUltralightC = true; - } else { - // 0xFF 0xFF would indicate Ultralight, but we also use Ultralight - // as a fallback if it's anything else - isUltralightC = false; - } - } else { - // See if we can find the NDEF CC in the OTP page and if it's - // smaller than major version two - if (respData[4] == (byte)0xE1 && ((respData[5] & 0xff) < 0x20)) { - // OK, got NDEF. Technically we'd have to search for the - // NDEF TLV as well. However, this would add too much - // time for discovery and we can make already make a good guess - // with the data we have here. Byte 2 of the OTP page - // indicates the size of the tag - 0x06 is UL, anything - // above indicates UL-C. - if ((respData[6] & 0xff) > 0x06) { - isUltralightC = true; - } - } else { - // Fall back to ultralight - isUltralightC = false; - } - } - } - return isUltralightC; - } - - @Override - public Bundle[] getTechExtras() { - synchronized (this) { - if (mTechExtras != null) return mTechExtras; - mTechExtras = new Bundle[mTechList.length]; - for (int i = 0; i < mTechList.length; i++) { - Bundle extras = new Bundle(); - switch (mTechList[i]) { - case TagTechnology.NFC_A: { - byte[] actBytes = mTechActBytes[i]; - if ((actBytes != null) && (actBytes.length > 0)) { - extras.putShort(NfcA.EXTRA_SAK, (short) (actBytes[0] & (short) 0xFF)); - } else { - // Unfortunately Jewel doesn't have act bytes, - // ignore this case. - } - extras.putByteArray(NfcA.EXTRA_ATQA, mTechPollBytes[i]); - break; - } - - case TagTechnology.NFC_B: { - // What's returned from the PN544 is actually: - // 4 bytes app data - // 3 bytes prot info - byte[] appData = new byte[4]; - byte[] protInfo = new byte[3]; - if (mTechPollBytes[i].length >= 7) { - System.arraycopy(mTechPollBytes[i], 0, appData, 0, 4); - System.arraycopy(mTechPollBytes[i], 4, protInfo, 0, 3); - - extras.putByteArray(NfcB.EXTRA_APPDATA, appData); - extras.putByteArray(NfcB.EXTRA_PROTINFO, protInfo); - } - break; - } - - case TagTechnology.NFC_F: { - byte[] pmm = new byte[8]; - byte[] sc = new byte[2]; - if (mTechPollBytes[i].length >= 8) { - // At least pmm is present - System.arraycopy(mTechPollBytes[i], 0, pmm, 0, 8); - extras.putByteArray(NfcF.EXTRA_PMM, pmm); - } - if (mTechPollBytes[i].length == 10) { - System.arraycopy(mTechPollBytes[i], 8, sc, 0, 2); - extras.putByteArray(NfcF.EXTRA_SC, sc); - } - break; - } - - case TagTechnology.ISO_DEP: { - if (hasTech(TagTechnology.NFC_A)) { - extras.putByteArray(IsoDep.EXTRA_HIST_BYTES, mTechActBytes[i]); - } - else { - extras.putByteArray(IsoDep.EXTRA_HI_LAYER_RESP, mTechActBytes[i]); - } - break; - } - - case TagTechnology.NFC_V: { - // First byte response flags, second byte DSFID - if (mTechPollBytes[i] != null && mTechPollBytes[i].length >= 2) { - extras.putByte(NfcV.EXTRA_RESP_FLAGS, mTechPollBytes[i][0]); - extras.putByte(NfcV.EXTRA_DSFID, mTechPollBytes[i][1]); - } - break; - } - - case TagTechnology.MIFARE_ULTRALIGHT: { - boolean isUlc = isUltralightC(); - extras.putBoolean(MifareUltralight.EXTRA_IS_UL_C, isUlc); - break; - } - - default: { - // Leave the entry in the array null - continue; - } - } - mTechExtras[i] = extras; - } - return mTechExtras; - } - } - - @Override - public NdefMessage findAndReadNdef() { - // Try to find NDEF on any of the technologies. - int[] technologies = getTechList(); - int[] handles = mTechHandles; - NdefMessage ndefMsg = null; - boolean foundFormattable = false; - int formattableHandle = 0; - int formattableLibNfcType = 0; - int status; - - for (int techIndex = 0; techIndex < technologies.length; techIndex++) { - // have we seen this handle before? - for (int i = 0; i < techIndex; i++) { - if (handles[i] == handles[techIndex]) { - continue; // don't check duplicate handles - } - } - - status = connectWithStatus(technologies[techIndex]); - if (status != 0) { - Log.d(TAG, "Connect Failed - status = "+ status); - if (status == STATUS_CODE_TARGET_LOST) { - break; - } - continue; // try next handle - } - // Check if this type is NDEF formatable - if (!foundFormattable) { - if (isNdefFormatable()) { - foundFormattable = true; - formattableHandle = getConnectedHandle(); - formattableLibNfcType = getConnectedLibNfcType(); - // We'll only add formattable tech if no ndef is - // found - this is because libNFC refuses to format - // an already NDEF formatted tag. - } - reconnect(); - } - - int[] ndefinfo = new int[2]; - status = checkNdefWithStatus(ndefinfo); - if (status != 0) { - Log.d(TAG, "Check NDEF Failed - status = " + status); - if (status == STATUS_CODE_TARGET_LOST) { - break; - } - continue; // try next handle - } - - // found our NDEF handle - boolean generateEmptyNdef = false; - - int supportedNdefLength = ndefinfo[0]; - int cardState = ndefinfo[1]; - byte[] buff = readNdef(); - if (buff != null) { - try { - ndefMsg = new NdefMessage(buff); - addNdefTechnology(ndefMsg, - getConnectedHandle(), - getConnectedLibNfcType(), - getConnectedTechnology(), - supportedNdefLength, cardState); - reconnect(); - } catch (FormatException e) { - // Create an intent anyway, without NDEF messages - generateEmptyNdef = true; - } - } else { - generateEmptyNdef = true; - } - - if (generateEmptyNdef) { - ndefMsg = null; - addNdefTechnology(null, - getConnectedHandle(), - getConnectedLibNfcType(), - getConnectedTechnology(), - supportedNdefLength, cardState); - reconnect(); - } - break; - } - - if (ndefMsg == null && foundFormattable) { - // Tag is not NDEF yet, and found a formattable target, - // so add formattable tech to tech list. - addNdefFormatableTechnology( - formattableHandle, - formattableLibNfcType); - } - - return ndefMsg; - } -} diff --git a/src/com/android/nfc/nxp/NativeP2pDevice.java b/src/com/android/nfc/nxp/NativeP2pDevice.java deleted file mode 100755 index 7c7db41..0000000 --- a/src/com/android/nfc/nxp/NativeP2pDevice.java +++ /dev/null @@ -1,77 +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.android.nfc.nxp; - -import com.android.nfc.DeviceHost.NfcDepEndpoint; - -/** - * Native interface to the P2P Initiator functions - */ -public class NativeP2pDevice implements NfcDepEndpoint { - - private int mHandle; - - private int mMode; - - private byte[] mGeneralBytes; - - private native byte[] doReceive(); - @Override - public byte[] receive() { - return doReceive(); - } - - private native boolean doSend(byte[] data); - @Override - public boolean send(byte[] data) { - return doSend(data); - } - - private native boolean doConnect(); - @Override - public boolean connect() { - return doConnect(); - } - - private native boolean doDisconnect(); - @Override - public boolean disconnect() { - return doDisconnect(); - } - - public native byte[] doTransceive(byte[] data); - @Override - public byte[] transceive(byte[] data) { - return doTransceive(data); - } - - @Override - public int getHandle() { - return mHandle; - } - - @Override - public int getMode() { - return mMode; - } - - @Override - public byte[] getGeneralBytes() { - return mGeneralBytes; - } - -} |