diff options
author | Martijn Coenen <maco@google.com> | 2012-07-25 08:56:11 -0700 |
---|---|---|
committer | Martijn Coenen <maco@google.com> | 2012-08-01 12:34:48 -0700 |
commit | 4b33b45ed7880968f9836213e2395dbd55e17b31 (patch) | |
tree | 6666e4f04a7bab7c9ec80bc7211303aec2c23810 /src/com | |
parent | 51a43593261ebf190f736ecbb3939b69479a21dc (diff) | |
download | packages_apps_nfc-4b33b45ed7880968f9836213e2395dbd55e17b31.zip packages_apps_nfc-4b33b45ed7880968f9836213e2395dbd55e17b31.tar.gz packages_apps_nfc-4b33b45ed7880968f9836213e2395dbd55e17b31.tar.bz2 |
Move NXP JNI and DeviceHost implementation into separate dir. (DO NOT MERGE)
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: I8579ec30ceb1908e4cd180cfbd10224aa4bddb8d
Diffstat (limited to 'src/com')
-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; - } - -} |