NFC integration
Source: Trusted_NFC_Device_Host_AA03.01e02_google.zip code drop (23-Sep-2010)
Conflicts:
core/java/android/app/ApplicationContext.java
core/java/android/provider/Settings.java
core/jni/Android.mk
core/jni/AndroidRuntime.cpp
core/res/AndroidManifest.xml
include/utils/Asset.h
Change-Id: I62c92f4c79f5ee65126c97602f6bc1c15794e573
Signed-off-by: Nick Pelly <npelly@google.com>
diff --git a/core/java/com/trustedlogic/trustednfc/android/ILlcpConnectionlessSocket.aidl b/core/java/com/trustedlogic/trustednfc/android/ILlcpConnectionlessSocket.aidl
new file mode 100644
index 0000000..35746ad
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/ILlcpConnectionlessSocket.aidl
@@ -0,0 +1,34 @@
+/*
+ * 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.trustedlogic.trustednfc.android;
+
+import com.trustedlogic.trustednfc.android.LlcpPacket;
+
+/**
+ * TODO
+ *
+ * {@hide}
+ */
+interface ILlcpConnectionlessSocket
+{
+
+ void close(int nativeHandle);
+ int getSap(int nativeHandle);
+ LlcpPacket receiveFrom(int nativeHandle);
+ int sendTo(int nativeHandle, in LlcpPacket packet);
+
+}
\ No newline at end of file
diff --git a/core/java/com/trustedlogic/trustednfc/android/ILlcpServiceSocket.aidl b/core/java/com/trustedlogic/trustednfc/android/ILlcpServiceSocket.aidl
new file mode 100644
index 0000000..5eb1f3c
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/ILlcpServiceSocket.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.trustedlogic.trustednfc.android;
+
+/**
+ * TODO
+ *
+ * {@hide}
+ */
+interface ILlcpServiceSocket
+{
+
+ int accept(int nativeHandle);
+ void close(int nativeHandle);
+ int getAcceptTimeout(int nativeHandle);
+ void setAcceptTimeout(int nativeHandle, int timeout);
+
+}
\ No newline at end of file
diff --git a/core/java/com/trustedlogic/trustednfc/android/ILlcpSocket.aidl b/core/java/com/trustedlogic/trustednfc/android/ILlcpSocket.aidl
new file mode 100644
index 0000000..e9169d8
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/ILlcpSocket.aidl
@@ -0,0 +1,41 @@
+/*
+ * 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.trustedlogic.trustednfc.android;
+
+/**
+ * TODO
+ *
+ * {@hide}
+ */
+interface ILlcpSocket
+{
+
+ int close(int nativeHandle);
+ int connect(int nativeHandle, int sap);
+ int connectByName(int nativeHandle, String sn);
+ int getConnectTimeout(int nativeHandle);
+ int getLocalSap(int nativeHandle);
+ int getLocalSocketMiu(int nativeHandle);
+ int getLocalSocketRw(int nativeHandle);
+ int getRemoteSocketMiu(int nativeHandle);
+ int getRemoteSocketRw(int nativeHandle);
+ int receive(int nativeHandle, out byte[] receiveBuffer);
+ int send(int nativeHandle, in byte[] data);
+ void setConnectTimeout(int nativeHandle, int timeout);
+
+}
+
diff --git a/core/java/com/trustedlogic/trustednfc/android/INdefTag.aidl b/core/java/com/trustedlogic/trustednfc/android/INdefTag.aidl
new file mode 100644
index 0000000..1f8d1a4
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/INdefTag.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.trustedlogic.trustednfc.android;
+
+import com.trustedlogic.trustednfc.android.NdefMessage;
+
+/**
+ * TODO
+ *
+ * {@hide}
+ */
+interface INdefTag
+{
+
+ NdefMessage read(int nativeHandle);
+ boolean write(int nativeHandle, in NdefMessage msg);
+
+}
\ No newline at end of file
diff --git a/core/java/com/trustedlogic/trustednfc/android/INfcManager.aidl b/core/java/com/trustedlogic/trustednfc/android/INfcManager.aidl
new file mode 100644
index 0000000..ce36ab2
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/INfcManager.aidl
@@ -0,0 +1,61 @@
+/*
+ * 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.trustedlogic.trustednfc.android;
+
+import com.trustedlogic.trustednfc.android.ILlcpSocket;
+import com.trustedlogic.trustednfc.android.ILlcpServiceSocket;
+import com.trustedlogic.trustednfc.android.ILlcpConnectionlessSocket;
+import com.trustedlogic.trustednfc.android.INfcTag;
+import com.trustedlogic.trustednfc.android.IP2pTarget;
+import com.trustedlogic.trustednfc.android.IP2pInitiator;
+
+
+/**
+ * Interface that allows controlling NFC activity.
+ *
+ * {@hide}
+ */
+interface INfcManager
+{
+
+ ILlcpSocket getLlcpInterface();
+ ILlcpConnectionlessSocket getLlcpConnectionlessInterface();
+ ILlcpServiceSocket getLlcpServiceInterface();
+ INfcTag getNfcTagInterface();
+ IP2pTarget getP2pTargetInterface();
+ IP2pInitiator getP2pInitiatorInterface();
+
+ void cancel();
+ int createLlcpConnectionlessSocket(int sap);
+ int createLlcpServiceSocket(int sap, String sn, int miu, int rw, int linearBufferLength);
+ int createLlcpSocket(int sap, int miu, int rw, int linearBufferLength);
+ int deselectSecureElement();
+ boolean disable();
+ boolean enable();
+ int getOpenTimeout();
+ String getProperties(String param);
+ int[] getSecureElementList();
+ int getSelectedSecureElement();
+ boolean isEnabled();
+ int openP2pConnection();
+ int openTagConnection();
+ int selectSecureElement(int seId);
+ void setOpenTimeout(int timeout);
+ int setProperties(String param, String value);
+
+}
+
diff --git a/core/java/com/trustedlogic/trustednfc/android/INfcTag.aidl b/core/java/com/trustedlogic/trustednfc/android/INfcTag.aidl
new file mode 100644
index 0000000..79543c4
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/INfcTag.aidl
@@ -0,0 +1,38 @@
+/*
+ * 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.trustedlogic.trustednfc.android;
+
+import com.trustedlogic.trustednfc.android.NdefMessage;
+
+/**
+ * TODO
+ *
+ * {@hide}
+ */
+interface INfcTag
+{
+
+ int close(int nativeHandle);
+ int connect(int nativeHandle);
+ String getType(int nativeHandle);
+ byte[] getUid(int nativeHandle);
+ boolean isNdef(int nativeHandle);
+ byte[] transceive(int nativeHandle, in byte[] data);
+
+ NdefMessage read(int nativeHandle);
+ boolean write(int nativeHandle, in NdefMessage msg);
+}
\ No newline at end of file
diff --git a/core/java/com/trustedlogic/trustednfc/android/IP2pInitiator.aidl b/core/java/com/trustedlogic/trustednfc/android/IP2pInitiator.aidl
new file mode 100644
index 0000000..96819ae
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/IP2pInitiator.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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.trustedlogic.trustednfc.android;
+
+/**
+ * TODO
+ *
+ * {@hide}
+ */
+interface IP2pInitiator
+{
+
+ byte[] getGeneralBytes(int nativeHandle);
+ int getMode(int nativeHandle);
+ byte[] receive(int nativeHandle);
+ boolean send(int nativeHandle, in byte[] data);
+
+}
\ No newline at end of file
diff --git a/core/java/com/trustedlogic/trustednfc/android/IP2pTarget.aidl b/core/java/com/trustedlogic/trustednfc/android/IP2pTarget.aidl
new file mode 100644
index 0000000..8dcdf18
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/IP2pTarget.aidl
@@ -0,0 +1,33 @@
+/*
+ * 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.trustedlogic.trustednfc.android;
+
+/**
+ * TODO
+ *
+ * {@hide}
+ */
+interface IP2pTarget
+{
+
+ byte[] getGeneralBytes(int nativeHandle);
+ int getMode(int nativeHandle);
+ int connect(int nativeHandle);
+ boolean disconnect(int nativeHandle);
+ byte[] transceive(int nativeHandle, in byte[] data);
+
+}
\ No newline at end of file
diff --git a/core/java/com/trustedlogic/trustednfc/android/LlcpConnectionlessSocket.java b/core/java/com/trustedlogic/trustednfc/android/LlcpConnectionlessSocket.java
new file mode 100644
index 0000000..0270626
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/LlcpConnectionlessSocket.java
@@ -0,0 +1,148 @@
+/*
+ * 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.
+ */
+
+/**
+ * File : LlcpConnectionLessSocket.java
+ * Original-Author : Trusted Logic S.A. (Daniel Tomas)
+ * Created : 18-02-2010
+ */
+
+package com.trustedlogic.trustednfc.android;
+
+import java.io.IOException;
+
+import com.trustedlogic.trustednfc.android.internal.ErrorCodes;
+
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * LlcpConnectionlessSocket represents a LLCP Connectionless object to be used
+ * in a connectionless communication
+ *
+ * @since AA02.01
+ * @hide
+ */
+public class LlcpConnectionlessSocket {
+
+
+ private static final String TAG = "LlcpConnectionlessSocket";
+
+ /**
+ * The handle returned by the NFC service and used to identify the LLCP connectionless socket in
+ * every call of this class.
+ *
+ * @hide
+ */
+ protected int mHandle;
+
+
+ /**
+ * The entry point for LLCP Connectionless socket operations.
+ *
+ * @hide
+ */
+ protected ILlcpConnectionlessSocket mService;
+
+
+ /**
+ * Internal constructor for the LlcpConnectionlessSocket class.
+ *
+ * @param service The entry point to the Nfc Service for LLCP Connectionless socket class.
+ * @param handle The handle returned by the NFC service and used to identify
+ * the socket in subsequent calls.
+ * @hide
+ */
+ LlcpConnectionlessSocket(ILlcpConnectionlessSocket service, int handle) {
+ this.mService = service;
+ this.mHandle = handle;
+ }
+
+ /**
+ * Send data to a specific LLCP Connectionless client
+ *
+ * @param packet Service Access Point number related to a LLCP
+ * Connectionless client and a data buffer to send
+ * @throws IOException if the LLCP link has been lost or deactivated.
+ * @since AA02.01
+ */
+ public void sendTo(LlcpPacket packet) throws IOException {
+ try {
+ int result = mService.sendTo(mHandle, packet);
+ // Handle potential errors
+ if (ErrorCodes.isError(result)) {
+ throw new IOException();
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in sendTo(): ", e);
+ }
+ }
+
+ /**
+ * Receive data from a LLCP Connectionless client
+ *
+ * @return data data received from a specific LLCP Connectionless client
+ * @throws IOException if the LLCP link has been lost or deactivated.
+ * @see LlcpPacket
+ * @since AA02.01
+ */
+ public LlcpPacket receiveFrom() throws IOException {
+ try {
+ LlcpPacket packet = mService.receiveFrom(mHandle);
+ if (packet != null) {
+ return packet;
+ }else{
+ // Handle potential errors
+ throw new IOException();
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in receiveFrom(): ", e);
+ }
+ return null;
+ }
+
+ /**
+ * Close the created Connectionless socket.
+ *
+ * @since AA02.01
+ */
+ public void close() {
+ try {
+ mService.close(mHandle);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in close(): ", e);
+ }
+ }
+
+ /**
+ * Returns the local Service Access Point number of the socket
+ *
+ * @return sap
+ * @since AA02.01
+ */
+ public int getSap() {
+ int sap = 0;
+
+ try {
+ sap = mService.getSap(mHandle);
+
+ } catch (RemoteException e) {
+
+ e.printStackTrace();
+ }
+ return sap;
+ }
+}
diff --git a/core/java/com/trustedlogic/trustednfc/android/LlcpException.java b/core/java/com/trustedlogic/trustednfc/android/LlcpException.java
new file mode 100644
index 0000000..1e2e2da
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/LlcpException.java
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/**
+ * File : LLCPException.java
+ * Original-Author : Trusted Logic S.A. (Daniel Tomas)
+ * Created : 24-02-2010
+ */
+
+package com.trustedlogic.trustednfc.android;
+
+/**
+ * Generic exception thrown in case something unexpected happened during a
+ * LLCP communication.
+ *
+ * @since AA02.01
+ * @hide
+ */
+public class LlcpException extends Exception {
+ /**
+ * Constructs a new LlcpException with the current stack trace and the
+ * specified detail message.
+ *
+ * @param s the detail message for this exception.
+ */
+ public LlcpException(String s) {
+ super(s);
+ }
+}
diff --git a/core/java/com/trustedlogic/trustednfc/android/LlcpPacket.aidl b/core/java/com/trustedlogic/trustednfc/android/LlcpPacket.aidl
new file mode 100644
index 0000000..297a1fe
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/LlcpPacket.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.trustedlogic.trustednfc.android;
+
+parcelable LlcpPacket;
diff --git a/core/java/com/trustedlogic/trustednfc/android/LlcpPacket.java b/core/java/com/trustedlogic/trustednfc/android/LlcpPacket.java
new file mode 100644
index 0000000..af79023
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/LlcpPacket.java
@@ -0,0 +1,119 @@
+/*
+ * 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.
+ */
+
+/**
+ * File : LLCPPacket.java
+ * Original-Author : Trusted Logic S.A. (Daniel Tomas)
+ * Created : 25-02-2010
+ */
+
+package com.trustedlogic.trustednfc.android;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Represents a LLCP packet received in a LLCP Connectionless communication;
+ *
+ * @since AA02.01
+ * @hide
+ */
+public class LlcpPacket implements Parcelable {
+
+ private int mRemoteSap;
+
+ private byte[] mDataBuffer;
+
+ /**
+ * Creator class, needed when implementing from Parcelable
+ * {@hide}
+ */
+ public static final Parcelable.Creator<LlcpPacket> CREATOR = new Parcelable.Creator<LlcpPacket>() {
+ public LlcpPacket createFromParcel(Parcel in) {
+ // Remote SAP
+ short sap = (short)in.readInt();
+
+ // Data Buffer
+ int dataLength = in.readInt();
+ byte[] data = new byte[dataLength];
+ in.readByteArray(data);
+
+ return new LlcpPacket(sap, data);
+ }
+
+ public LlcpPacket[] newArray(int size) {
+ return new LlcpPacket[size];
+ }
+ };
+
+
+ /**
+ * Creates a LlcpPacket to be sent to a remote Service Access Point number
+ * (SAP)
+ *
+ * @param sap Remote Service Access Point number
+ * @param data Data buffer
+ * @since AA02.01
+ */
+ public LlcpPacket(int sap, byte[] data) {
+ mRemoteSap = sap;
+ mDataBuffer = data;
+ }
+
+ /**
+ * @hide
+ */
+ public LlcpPacket() {
+ }
+
+ /**
+ * Returns the remote Service Access Point number
+ *
+ * @return remoteSap
+ * @since AA02.01
+ */
+ public int getRemoteSap() {
+ return mRemoteSap;
+ }
+
+ /**
+ * Returns the data buffer
+ *
+ * @return data
+ * @since AA02.01
+ */
+ public byte[] getDataBuffer() {
+ return mDataBuffer;
+ }
+
+ /**
+ * (Parcelable) Describe the parcel
+ * {@hide}
+ */
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * (Parcelable) Convert current object to a Parcel
+ * {@hide}
+ */
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mRemoteSap);
+ dest.writeInt(mDataBuffer.length);
+ dest.writeByteArray(mDataBuffer);
+ }
+}
diff --git a/core/java/com/trustedlogic/trustednfc/android/LlcpServiceSocket.java b/core/java/com/trustedlogic/trustednfc/android/LlcpServiceSocket.java
new file mode 100644
index 0000000..a152ecb1
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/LlcpServiceSocket.java
@@ -0,0 +1,180 @@
+/*
+ * 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.
+ */
+
+/**
+ * File : LLCPServerSocket.java
+ * Original-Author : Trusted Logic S.A. (Daniel Tomas)
+ * Created : 18-02-2010
+ */
+
+package com.trustedlogic.trustednfc.android;
+
+import java.io.IOException;
+
+import com.trustedlogic.trustednfc.android.internal.ErrorCodes;
+
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * LlcpServiceSocket represents a LLCP Service to be used in a
+ * Connection-oriented communication
+ *
+ * @since AA02.01
+ * @hide
+ */
+public class LlcpServiceSocket {
+
+ private static final String TAG = "LlcpServiceSocket";
+
+ /**
+ * The handle returned by the NFC service and used to identify the LLCP
+ * Service socket in every call of this class.
+ *
+ * @hide
+ */
+ protected int mHandle;
+
+ /**
+ * The entry point for LLCP Service socket operations.
+ *
+ * @hide
+ */
+ protected ILlcpServiceSocket mService;
+
+ private ILlcpSocket mLlcpSocketService;
+
+ static LlcpException convertErrorToLlcpException(int errorCode) {
+ return convertErrorToLlcpException(errorCode, null);
+ }
+
+ static LlcpException convertErrorToLlcpException(int errorCode,
+ String message) {
+ if (message == null) {
+ message = "";
+ } else {
+ message = " (" + message + ")";
+ }
+
+ switch (errorCode) {
+ case ErrorCodes.ERROR_SOCKET_CREATION:
+ return new LlcpException(
+ "Error during the creation of an Llcp socket" + message);
+ case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES:
+ return new LlcpException("Not enough ressources are available"
+ + message);
+ default:
+ return new LlcpException("Unkown error code " + errorCode + message);
+ }
+ }
+
+ /**
+ * Internal constructor for the LlcpServiceSocket class.
+ *
+ * @param service
+ * The entry point to the Nfc Service for LlcpServiceSocket
+ * class.
+ * @param handle
+ * The handle returned by the NFC service and used to identify
+ * the socket in subsequent calls.
+ * @hide
+ */
+ LlcpServiceSocket(ILlcpServiceSocket service, ILlcpSocket socketService, int handle) {
+ this.mService = service;
+ this.mHandle = handle;
+ this.mLlcpSocketService = socketService;
+ }
+
+ /**
+ * Wait for incomming connection request from a LLCP client and accept this
+ * request
+ *
+ * @return socket object to be used to communicate with a LLCP client
+ *
+ * @throws IOException
+ * if the llcp link is lost or deactivated
+ * @throws LlcpException
+ * if not enough ressources are available
+ *
+ * @see LlcpSocket
+ * @since AA02.01
+ */
+ public LlcpSocket accept() throws IOException, LlcpException {
+
+ try {
+ int handle = mService.accept(mHandle);
+ // Handle potential errors
+ if (ErrorCodes.isError(handle)) {
+ if (handle == ErrorCodes.ERROR_IO) {
+ throw new IOException();
+ } else {
+ throw convertErrorToLlcpException(handle);
+ }
+ }
+
+ // Build the public LlcpSocket object
+ return new LlcpSocket(mLlcpSocketService, handle);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in accept(): ", e);
+ return null;
+ }
+
+ }
+
+ /**
+ * Set the timeout for the accept request
+ *
+ * @param timeout
+ * value of the timeout for the accept request
+ * @since AA02.01
+ */
+ public void setAcceptTimeout(int timeout) {
+ try {
+ mService.setAcceptTimeout(mHandle, timeout);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in setAcceptTimeout(): ", e);
+ }
+ }
+
+ /**
+ * Get the timeout value of the accept request
+ *
+ * @return mTimeout
+ * @since AA02.01
+ */
+ public int getAcceptTimeout() {
+ try {
+ return mService.getAcceptTimeout(mHandle);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in getAcceptTimeout(): ", e);
+ return 0;
+ }
+ }
+
+ /**
+ * Close the created Llcp Service socket
+ *
+ * @since AA02.01
+ */
+ public void close() {
+ try {
+ mService.close(mHandle);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in close(): ", e);
+ }
+ }
+
+}
diff --git a/core/java/com/trustedlogic/trustednfc/android/LlcpSocket.java b/core/java/com/trustedlogic/trustednfc/android/LlcpSocket.java
new file mode 100644
index 0000000..e47160c
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/LlcpSocket.java
@@ -0,0 +1,344 @@
+/*
+ * 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.
+ */
+
+/**
+ * File : LlcpClientSocket.java
+ * Original-Author : Trusted Logic S.A. (Daniel Tomas)
+ * Created : 18-02-2010
+ */
+
+package com.trustedlogic.trustednfc.android;
+
+import java.io.IOException;
+
+import com.trustedlogic.trustednfc.android.internal.ErrorCodes;
+
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * LlcpClientSocket represents a LLCP Connection-Oriented client to be used in a
+ * connection-oriented communication
+ *
+ * @since AA02.01
+ * @hide
+ */
+public class LlcpSocket {
+
+ private static final String TAG = "LlcpSocket";
+
+ /**
+ * The handle returned by the NFC service and used to identify the LLCP
+ * socket in every call of this class.
+ *
+ * @hide
+ */
+ protected int mHandle;
+
+ /**
+ * The entry point for LLCP socket operations.
+ *
+ * @hide
+ */
+ protected ILlcpSocket mService;
+
+ static LlcpException convertErrorToLlcpException(int errorCode) {
+ return convertErrorToLlcpException(errorCode, null);
+ }
+
+ static LlcpException convertErrorToLlcpException(int errorCode,
+ String message) {
+ if (message == null) {
+ message = "";
+ } else {
+ message = " (" + message + ")";
+ }
+
+ switch (errorCode) {
+ case ErrorCodes.ERROR_SOCKET_CREATION:
+ return new LlcpException(
+ "Error during the creation of an Llcp socket" + message);
+ case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES:
+ return new LlcpException("Not enough ressources are available"
+ + message);
+ case ErrorCodes.ERROR_SOCKET_NOT_CONNECTED:
+ return new LlcpException("Socket not connected to an Llcp Service"
+ + message);
+ default:
+ return new LlcpException("Unkown error code " + errorCode + message);
+ }
+ }
+
+ /**
+ * Internal constructor for the LlcpSocket class.
+ *
+ * @param service
+ * The entry point to the Nfc Service for LlcpServiceSocket
+ * class.
+ * @param handle
+ * The handle returned by the NFC service and used to identify
+ * the socket in subsequent calls.
+ * @hide
+ */
+ LlcpSocket(ILlcpSocket service, int handle) {
+ this.mService = service;
+ this.mHandle = handle;
+ }
+
+ /**
+ * Connect request to a specific LLCP Service by its SAP.
+ *
+ * @param sap
+ * Service Access Point number of the LLCP Service
+ * @throws IOException
+ * if the LLCP has been lost or deactivated.
+ * @throws LlcpException
+ * if the connection request is rejected by the remote LLCP
+ * Service
+ * @since AA02.01
+ */
+ public void connect(int sap) throws IOException, LlcpException {
+ try {
+ int result = mService.connect(mHandle, sap);
+ // Handle potential errors
+ if (ErrorCodes.isError(result)) {
+ if (result == ErrorCodes.ERROR_IO) {
+ throw new IOException();
+ } else {
+ throw convertErrorToLlcpException(result);
+ }
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in accept(): ", e);
+ }
+ }
+
+ /**
+ * Connect request to a specific LLCP Service by its Service Name.
+ *
+ * @param sn
+ * Service Name of the LLCP Service
+ * @throws IOException
+ * if the LLCP has been lost or deactivated.
+ * @throws LlcpException
+ * if the connection request is rejected by the remote LLCP
+ * Service
+ * @since AA02.01
+ */
+ public void connect(String sn) throws IOException, LlcpException {
+ try {
+ int result = mService.connectByName(mHandle, sn);
+ // Handle potential errors
+ if (ErrorCodes.isError(result)) {
+ if (result == ErrorCodes.ERROR_IO) {
+ throw new IOException();
+ } else {
+ throw convertErrorToLlcpException(result);
+ }
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in accept(): ", e);
+ }
+ }
+
+ /**
+ * Set the timeout for the connect request
+ *
+ * @param timeout
+ * timeout value for the connect request
+ * @since AA02.01
+ */
+ public void setConnectTimeout(int timeout) {
+ try {
+ mService.setConnectTimeout(mHandle, timeout);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in setConnectTimeout(): ", e);
+ }
+ }
+
+ /**
+ * Get the timeout value of the connect request
+ *
+ * @return mTimeout
+ * @since AA02.01
+ */
+ public int getConnectTimeout() {
+ try {
+ return mService.getConnectTimeout(mHandle);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in getConnectTimeout(): ", e);
+ return 0;
+ }
+ }
+
+ /**
+ * Disconnect request to the connected LLCP socket and close the created
+ * socket.
+ *
+ * @throws IOException
+ * if the LLCP has been lost or deactivated.
+ * @since AA02.01
+ */
+ public void close() throws IOException {
+ try {
+ int result = mService.close(mHandle);
+ // Handle potential errors
+ if (ErrorCodes.isError(result)) {
+ throw new IOException();
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in close(): ", e);
+ }
+ }
+
+ /**
+ * Send data to the connected LLCP Socket.
+ *
+ * @throws IOException
+ * if the LLCP has been lost or deactivated.
+ * @since AA02.01
+ */
+ public void send(byte[] data) throws IOException {
+ try {
+ int result = mService.send(mHandle, data);
+ // Handle potential errors
+ if (ErrorCodes.isError(result)) {
+ throw new IOException();
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in send(): ", e);
+ }
+ }
+
+ /**
+ * Receive data from the connected LLCP socket
+ *
+ * @param receiveBuffer
+ * a buffer for the received data
+ * @return length length of the data received
+ * @throws IOException
+ * if the LLCP has been lost or deactivated.
+ * @since AA02.01
+ */
+ public int receive(byte[] receiveBuffer) throws IOException {
+ int receivedLength = 0;
+ try {
+ receivedLength = mService.receive(mHandle, receiveBuffer);
+ if(receivedLength == 0){
+ throw new IOException();
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in send(): ", e);
+ }
+
+ return receivedLength;
+ }
+
+ /**
+ * Returns the local Service Access Point number of the socket
+ *
+ * @return localSap
+ * @since AA02.01
+ */
+ public int getLocalSap() {
+ try {
+ return mService.getLocalSap(mHandle);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in getLocalSap(): ", e);
+ return 0;
+ }
+ }
+
+ /**
+ * Returns the local Maximum Information Unit(MIU) of the socket
+ *
+ * @return miu
+ * @since AA02.01
+ */
+ public int getLocalSocketMiu() {
+ try {
+ return mService.getLocalSocketMiu(mHandle);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in getLocalSocketMiu(): ", e);
+ return 0;
+ }
+ }
+
+ /**
+ * Returns the local Receive Window(RW) of the socket
+ *
+ * @return rw
+ * @since AA02.01
+ */
+ public int getLocalSocketRw() {
+ try {
+ return mService.getLocalSocketRw(mHandle);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in getLocalSocketRw(): ", e);
+ return 0;
+ }
+ }
+
+ /**
+ * Returns the remote Maximum Information Unit(MIU) of the socket.
+ * <p>
+ * This method must be called when the socket is in CONNECTED_STATE
+ *
+ * @return remoteMiu
+ * @throws LlcpException
+ * if the LlcpClientSocket is not in a CONNECTED_STATE
+ * @since AA02.01
+ */
+ public int getRemoteSocketMiu() throws LlcpException {
+ try {
+ int result = mService.getRemoteSocketMiu(mHandle);
+ if(result != ErrorCodes.ERROR_SOCKET_NOT_CONNECTED){
+ return result;
+ }else{
+ throw convertErrorToLlcpException(result);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in getRemoteSocketMiu(): ", e);
+ return 0;
+ }
+ }
+
+ /**
+ * Returns the remote Receive Window(RW) of the connected remote socket.
+ * <p>
+ * This method must be called when the socket is in CONNECTED_STATE
+ *
+ * @return rw
+ * @throws LlcpException
+ * if the LlcpClientSocket is not in a CONNECTED_STATE
+ * @since AA02.01
+ */
+ public int getRemoteSocketRw() throws LlcpException {
+ try {
+ int result = mService.getRemoteSocketRw(mHandle);
+ if( result != ErrorCodes.ERROR_SOCKET_NOT_CONNECTED){
+ return result;
+ }else{
+ throw convertErrorToLlcpException(result);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in getRemoteSocketRw(): ", e);
+ return 0;
+ }
+ }
+
+
+}
diff --git a/core/java/com/trustedlogic/trustednfc/android/NdefMessage.aidl b/core/java/com/trustedlogic/trustednfc/android/NdefMessage.aidl
new file mode 100644
index 0000000..e60f4e8
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/NdefMessage.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.trustedlogic.trustednfc.android;
+
+parcelable NdefMessage;
diff --git a/core/java/com/trustedlogic/trustednfc/android/NdefMessage.java b/core/java/com/trustedlogic/trustednfc/android/NdefMessage.java
new file mode 100644
index 0000000..f03b604
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/NdefMessage.java
@@ -0,0 +1,160 @@
+/*
+ * 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.
+ */
+
+/**
+ * File : NDEFMessage.java
+ * Original-Author : Trusted Logic S.A. (Jeremie Corbier)
+ * Created : 05-10-2009
+ */
+
+package com.trustedlogic.trustednfc.android;
+
+import java.util.LinkedList;
+import java.util.ListIterator;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Represents an NDEF message as specified by the <a
+ * href="http://www.nfc-forum.org/">NFC Forum</a>.
+ *
+ * @see NdefRecord
+ *
+ * @since AA01.04
+ * @hide
+ */
+public class NdefMessage implements Parcelable {
+ /* Flag values */
+ private static final int FLAG_MB = 0x80;
+ private static final int FLAG_ME = 0x40;
+ private static final int FLAG_CF = 0x20;
+ private static final int FLAG_SR = 0x10;
+ private static final int FLAG_IL = 0x08;
+
+ /**
+ * Array of {@link NdefRecord} composing this message.
+ */
+ private NdefRecord[] mRecords;
+
+ /**
+ * Builds an NDEF message.
+ *
+ * @param data raw NDEF message data
+ *
+ * @throws NFCException
+ */
+ public NdefMessage(byte[] data) throws NfcException {
+ if (parseNdefMessage(data) == -1)
+ throw new NfcException("Error while parsing NDEF message");
+ }
+
+ /**
+ * Builds an NDEF message.
+ *
+ * @param records
+ * an array of already created NDEF records
+ */
+ public NdefMessage(NdefRecord[] records) {
+ mRecords = new NdefRecord[records.length];
+
+ System.arraycopy(records, 0, mRecords, 0, records.length);
+ }
+
+ /**
+ * Returns the NDEF message as a byte array.
+ *
+ * @return the message as a byte array
+ */
+ public byte[] toByteArray() {
+ if ((mRecords == null) || (mRecords.length == 0))
+ return null;
+
+ byte[] msg = {};
+
+ for (int i = 0; i < mRecords.length; i++) {
+ byte[] record = mRecords[i].toByteArray();
+ byte[] tmp = new byte[msg.length + record.length];
+
+ /* Make sure the Message Begin flag is set only for the first record */
+ if (i == 0)
+ record[0] |= FLAG_MB;
+ else
+ record[0] &= ~FLAG_MB;
+
+ /* Make sure the Message End flag is set only for the last record */
+ if (i == (mRecords.length - 1))
+ record[0] |= FLAG_ME;
+ else
+ record[0] &= ~FLAG_ME;
+
+ System.arraycopy(msg, 0, tmp, 0, msg.length);
+ System.arraycopy(record, 0, tmp, msg.length, record.length);
+
+ msg = tmp;
+ }
+
+ return msg;
+ }
+
+ /**
+ * Returns an array of {@link NdefRecord} composing this message.
+ *
+ * @return mRecords
+ *
+ * @since AA02.01
+ */
+ public NdefRecord[] getRecords(){
+ return mRecords;
+ }
+
+ private native int parseNdefMessage(byte[] data);
+
+ /**
+ * (Parcelable) Describe the parcel
+ * {@hide}
+ */
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * (Parcelable) Convert current object to a Parcel
+ * {@hide}
+ */
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mRecords.length);
+ dest.writeTypedArray(mRecords, 0);
+ }
+
+ /**
+ * Creator class, needed when implementing from Parcelable
+ * {@hide}
+ */
+ public static final Parcelable.Creator<NdefMessage> CREATOR = new Parcelable.Creator<NdefMessage>() {
+ public NdefMessage createFromParcel(Parcel in) {
+ int recordsLength = in.readInt();
+ NdefRecord[] records = new NdefRecord[recordsLength];
+ in.readTypedArray(records, NdefRecord.CREATOR);
+ return new NdefMessage(records);
+ }
+
+ public NdefMessage[] newArray(int size) {
+ return new NdefMessage[size];
+ }
+ };
+
+}
diff --git a/core/java/com/trustedlogic/trustednfc/android/NdefRecord.aidl b/core/java/com/trustedlogic/trustednfc/android/NdefRecord.aidl
new file mode 100644
index 0000000..9d95174
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/NdefRecord.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.trustedlogic.trustednfc.android;
+
+parcelable NdefRecord;
diff --git a/core/java/com/trustedlogic/trustednfc/android/NdefRecord.java b/core/java/com/trustedlogic/trustednfc/android/NdefRecord.java
new file mode 100644
index 0000000..a0257fe
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/NdefRecord.java
@@ -0,0 +1,293 @@
+/*
+ * 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.
+ */
+
+/**
+ * File : NdefRecord.java
+ * Original-Author : Trusted Logic S.A. (Jeremie Corbier)
+ * Created : 05-10-2009
+ */
+
+package com.trustedlogic.trustednfc.android;
+
+import android.location.Location;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * An NDEF record as specified by the <a href="http://www.nfc-forum.org/">NFC
+ * Forum</a>.
+ *
+ * @see NdefMessage
+ *
+ * @since AA01.04
+ * @hide
+ */
+public class NdefRecord implements Parcelable {
+
+ /**
+ * Type Name Format - Empty record
+ */
+ public static final short TNF_EMPTY = 0x0;
+
+ /**
+ * Type Name Format - NFC Forum-defined type
+ */
+ public static final short TNF_WELL_KNOWN_TYPE = 0x1;
+
+ /**
+ * Type Name Format - RFC2045 MIME type
+ */
+ public static final short TNF_MIME_MEDIA_TYPE = 0x2;
+
+ /**
+ * Type Name Format - Absolute URI
+ */
+ public static final short TNF_ABSOLUTE_URI = 0x3;
+
+ /**
+ * Type Name Format - User-defined type
+ */
+ public static final short TNF_EXTERNAL_TYPE = 0x4;
+
+ /**
+ * Type Name Format - Unknown type
+ */
+ public static final short TNF_UNKNOWN = 0x5;
+
+ /**
+ * Type Name Format - Unchanged. This TNF is used for chunked records, so
+ * that middle records inherits from the first record's type.
+ */
+ public static final short TNF_UNCHANGED = 0x6;
+
+ /**
+ * NFC Forum-defined Type - Smart Poster
+ */
+ public static final byte[] TYPE_SMART_POSTER = { 0x53, 0x70 };
+
+ /**
+ * NFC Forum-defined Type - Text
+ */
+ public static final byte[] TYPE_TEXT = { 0x54 };
+
+ /**
+ * NFC Forum-defined Type - URI
+ */
+ public static final byte[] TYPE_URI = { 0x55 };
+
+ /**
+ * NFC Forum-defined Global Type - Connection Handover Request
+ */
+ public static final byte[] TYPE_HANDOVER_REQUEST = { 0x48, 0x72 };
+
+ /**
+ * NFC Forum-defined Global Type - Connection Handover Select
+ */
+ public static final byte[] TYPE_HANDOVER_SELECT = { 0x48, 0x73 };
+
+ /**
+ * NFC Forum-defined Global Type - Connection Handover Carrier
+ */
+ public static final byte[] TYPE_HANDOVER_CARRIER = { 0x48, 0x63 };
+
+ /**
+ * NFC Forum-defined Local Type - Alternative Carrier
+ */
+ public static final byte[] TYPE_ALTERNATIVE_CARRIER = { 0x61, 0x63 };
+
+ /* Flag values */
+ private static final int FLAG_MB = 0x80;
+ private static final int FLAG_ME = 0x40;
+ private static final int FLAG_CF = 0x20;
+ private static final int FLAG_SR = 0x10;
+ private static final int FLAG_IL = 0x08;
+
+ /**
+ * Record Flags
+ */
+ private short mFlags = 0;
+
+ /**
+ * Record Type Name Format
+ */
+ private short mTnf = 0;
+
+ /**
+ * Record Type
+ */
+ private byte[] mType = null;
+
+ /**
+ * Record Identifier
+ */
+ private byte[] mId = null;
+
+ /**
+ * Record Payload
+ */
+ private byte[] mPayload = null;
+
+ /**
+ * Creates an NdefRecord given its Type Name Format, its type, its id and
+ * its.
+ *
+ * @param tnf
+ * Type Name Format
+ * @param type
+ * record type
+ * @param id
+ * record id (optional, can be null)
+ * @param data
+ * record payload
+ */
+ public NdefRecord(short tnf, byte[] type, byte[] id, byte[] data) {
+
+ /* generate flag */
+ mFlags = FLAG_MB | FLAG_ME;
+
+ /* Determine if it is a short record */
+ if(data.length < 0xFF)
+ {
+ mFlags |= FLAG_SR;
+ }
+
+ /* Determine if an id is present */
+ if(id.length != 0)
+ {
+ mFlags |= FLAG_IL;
+ }
+
+ mTnf = tnf;
+ mType = (byte[]) type.clone();
+ mId = (byte[]) id.clone();
+ mPayload = (byte[]) data.clone();
+ }
+
+ /**
+ * Appends data to the record's payload.
+ *
+ * @param data
+ * Data to be added to the record.
+ */
+ public void appendPayload(byte[] data) {
+ byte[] newPayload = new byte[mPayload.length + data.length];
+
+ System.arraycopy(mPayload, 0, newPayload, 0, mPayload.length);
+ System.arraycopy(data, 0, newPayload, mPayload.length, data.length);
+
+ mPayload = newPayload;
+ }
+
+ /**
+ * Returns record as a byte array.
+ *
+ * @return record as a byte array.
+ */
+ public byte[] toByteArray() {
+ return generate(mFlags, mTnf, mType, mId, mPayload);
+ }
+
+ private native byte[] generate(short flags, short tnf, byte[] type,
+ byte[] id, byte[] data);
+
+ /**
+ * (Parcelable) Describe the parcel
+ * {@hide}
+ */
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * (Parcelable) Convert current object to a Parcel
+ * {@hide}
+ */
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mTnf);
+ dest.writeInt(mType.length);
+ dest.writeByteArray(mType);
+ dest.writeInt(mId.length);
+ dest.writeByteArray(mId);
+ dest.writeInt(mPayload.length);
+ dest.writeByteArray(mPayload);
+ }
+
+ /**
+ * Creator class, needed when implementing from Parcelable
+ * {@hide}
+ */
+ public static final Parcelable.Creator<NdefRecord> CREATOR = new Parcelable.Creator<NdefRecord>() {
+ public NdefRecord createFromParcel(Parcel in) {
+ // TNF
+ short tnf = (short)in.readInt();
+ // Type
+ int typeLength = in.readInt();
+ byte[] type = new byte[typeLength];
+ in.readByteArray(type);
+ // ID
+ int idLength = in.readInt();
+ byte[] id = new byte[idLength];
+ in.readByteArray(id);
+ // Payload
+ int payloadLength = in.readInt();
+ byte[] payload = new byte[payloadLength];
+ in.readByteArray(payload);
+
+ return new NdefRecord(tnf, type, id, payload);
+ }
+
+ public NdefRecord[] newArray(int size) {
+ return new NdefRecord[size];
+ }
+ };
+
+ /**
+ * Returns record TNF
+ *
+ * @return mTnf
+ */
+ public int getTnf(){
+ return mTnf;
+ }
+
+ /**
+ * Returns record TYPE
+ *
+ * @return mType
+ */
+ public byte[] getType(){
+ return mType;
+ }
+
+ /**
+ * Returns record ID
+ *
+ * @return mId
+ */
+ public byte[] getId(){
+ return mId;
+ }
+
+ /**
+ * Returns record Payload
+ *
+ * @return mPayload
+ */
+ public byte[] getPayload(){
+ return mPayload;
+ }
+
+}
diff --git a/core/java/com/trustedlogic/trustednfc/android/NdefTag.java b/core/java/com/trustedlogic/trustednfc/android/NdefTag.java
new file mode 100644
index 0000000..1d99241
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/NdefTag.java
@@ -0,0 +1,126 @@
+/*
+ * 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.
+ */
+
+/**
+ * File : NDEFTag.java
+ * Original-Author : Trusted Logic S.A. (Jeremie Corbier)
+ * Created : 04-12-2009
+ */
+
+package com.trustedlogic.trustednfc.android;
+
+import java.io.IOException;
+
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * NdefTag represents tags complying with the NFC Forum's NFC Data Exchange
+ * Format.
+ *
+ * @since AA01.04
+ * @hide
+ */
+public class NdefTag extends NfcTag {
+
+ private static final String TAG = "NdefTag";
+
+
+ public NdefTag(NfcTag tag){
+ super(tag.mService,tag.mHandle);
+ this.isConnected = tag.isConnected;
+ this.isClosed = tag.isClosed;
+ tag.isClosed = false;
+ }
+
+ /**
+ * Internal constructor for the NfcNdefTag class.
+ *
+ * @param service The entry point to the Nfc Service for NfcNdefTag class.
+ * @param handle The handle returned by the NFC service and used to identify
+ * the tag in subsequent calls.
+ * @hide
+ */
+ NdefTag(INfcTag service, int handle) {
+ super(service, handle);
+ }
+
+ /**
+ * Read NDEF data from an NDEF tag.
+ *
+ * @return the NDEF message read from the tag.
+ * @throws NfcException if the tag is not NDEF-formatted.
+ * @throws IOException if the target has been lost or the connection has
+ * been closed.
+ * @see NdefMessage
+ */
+ public NdefMessage read() throws NfcException, IOException {
+ // Check state
+ checkState();
+
+ //Check if the tag is Ndef compliant
+ if(isNdef != true){
+ isNdef = isNdef();
+ if(isNdef != true) {
+ throw new NfcException("Tag is not NDEF compliant");
+ }
+ }
+
+ // Perform transceive
+ try {
+ NdefMessage msg = mService.read(mHandle);
+ if (msg == null) {
+ throw new IOException("NDEF read failed");
+ }
+ return msg;
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in read(): ", e);
+ return null;
+ }
+ }
+
+ /**
+ * Write NDEF data to an NDEF-compliant tag.
+ *
+ * @param msg NDEF message to be written to the tag.
+ * @throws NfcException if the tag is not NDEF formatted.
+ * @throws IOException if the target has been lost or the connection has
+ * been closed.
+ * @see NdefMessage
+ */
+ public void write(NdefMessage msg) throws NfcException, IOException {
+ // Check state
+ checkState();
+
+ //Check if the tag is Ndef compliant
+ if(isNdef != true){
+ isNdef = isNdef();
+ if(isNdef != true) {
+ throw new NfcException("Tag is not NDEF compliant");
+ }
+ }
+
+ // Perform transceive
+ try {
+ boolean isSuccess = mService.write(mHandle, msg);
+ if (!isSuccess) {
+ throw new IOException("NDEF write failed");
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in write(): ", e);
+ }
+ }
+}
diff --git a/core/java/com/trustedlogic/trustednfc/android/NfcException.java b/core/java/com/trustedlogic/trustednfc/android/NfcException.java
new file mode 100644
index 0000000..2497c15
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/NfcException.java
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+/**
+ * File : NFCException.java
+ * Original-Author : Trusted Logic S.A. (Jeremie Corbier)
+ * Created : 26-08-2009
+ */
+
+package com.trustedlogic.trustednfc.android;
+
+/**
+ * Generic exception thrown in case something unexpected happened during the
+ * NFCManager operations.
+ *
+ * @since AA01.04
+ * @hide
+ */
+public class NfcException extends Exception {
+ /**
+ * Constructs a new NfcException with the current stack trace and the
+ * specified detail message.
+ *
+ * @param s the detail message for this exception.
+ */
+ public NfcException(String s) {
+ super(s);
+ }
+}
diff --git a/core/java/com/trustedlogic/trustednfc/android/NfcManager.java b/core/java/com/trustedlogic/trustednfc/android/NfcManager.java
new file mode 100644
index 0000000..98ab5bf
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/NfcManager.java
@@ -0,0 +1,656 @@
+/*
+ * 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.
+ */
+
+/**
+ * File : NfcManager.java
+ * Original-Author : Trusted Logic S.A. (Jeremie Corbier)
+ * Created : 26-08-2009
+ */
+
+package com.trustedlogic.trustednfc.android;
+
+import java.io.IOException;
+
+import com.trustedlogic.trustednfc.android.internal.ErrorCodes;
+
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.media.MiniThumbFile;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.util.Log;
+
+//import android.util.Log;
+
+/**
+ * This class provides the primary API for managing all aspects of NFC. Get an
+ * instance of this class by calling
+ * Context.getSystemService(Context.NFC_SERVICE).
+ * @hide
+ */
+public final class NfcManager {
+ /**
+ * Tag Reader Discovery mode
+ */
+ private static final int DISCOVERY_MODE_TAG_READER = 0;
+
+ /**
+ * NFC-IP1 Peer-to-Peer mode Enables the manager to act as a peer in an
+ * NFC-IP1 communication. Implementations should not assume that the
+ * controller will end up behaving as an NFC-IP1 target or initiator and
+ * should handle both cases, depending on the type of the remote peer type.
+ */
+ private static final int DISCOVERY_MODE_NFCIP1 = 1;
+
+ /**
+ * Card Emulation mode Enables the manager to act as an NFC tag. Provided
+ * that a Secure Element (an UICC for instance) is connected to the NFC
+ * controller through its SWP interface, it can be exposed to the outside
+ * NFC world and be addressed by external readers the same way they would
+ * with a tag.
+ * <p>
+ * Which Secure Element is exposed is implementation-dependent.
+ *
+ * @since AA01.04
+ */
+ private static final int DISCOVERY_MODE_CARD_EMULATION = 2;
+
+ /**
+ * Used as Parcelable extra field in
+ * {@link com.trustedlogic.trustednfc.android.NfcManager#NDEF_TAG_DISCOVERED_ACTION}
+ * . It contains the NDEF message read from the NDEF tag discovered.
+ */
+ public static final String NDEF_MESSAGE_EXTRA = "com.trustedlogic.trustednfc.android.extra.NDEF_MESSAGE";
+
+ /**
+ * Broadcast Action: a NDEF tag has been discovered.
+ * <p>
+ * Always contains the extra field
+ * {@link com.trustedlogic.trustednfc.android.NfcManager#NDEF_MESSAGE_EXTRA}.
+ * <p class="note">
+ * <strong>Note:</strong> Requires the NFC_NOTIFY permission.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String NDEF_TAG_DISCOVERED_ACTION = "com.trustedlogic.trustednfc.android.action.NDEF_TAG_DISCOVERED";
+
+ /**
+ * Used as byte array extra field in
+ * {@link com.trustedlogic.trustednfc.android.NfcManager#TRANSACTION_DETECTED_ACTION}
+ * . It contains the AID of the applet concerned by the transaction.
+ */
+ public static final String AID_EXTRA = "com.trustedlogic.trustednfc.android.extra.AID";
+
+ /**
+ * Broadcast Action: a transaction with a secure element has been detected.
+ * <p>
+ * Always contains the extra field
+ * {@link com.trustedlogic.trustednfc.android.NfcManager#AID_EXTRA}
+ * <p class="note">
+ * <strong>Note:</strong> Requires the NFC_NOTIFY permission
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String TRANSACTION_DETECTED_ACTION = "com.trustedlogic.trustednfc.android.action.TRANSACTION_DETECTED";
+
+ /**
+ * LLCP link status: The LLCP link is activated.
+ *
+ * @since AA02.01
+ */
+ public static final int LLCP_LINK_STATE_ACTIVATED = 0;
+
+ /**
+ * LLCP link status: The LLCP link is deactivated.
+ *
+ * @since AA02.01
+ */
+ public static final int LLCP_LINK_STATE_DEACTIVATED = 1;
+
+ /**
+ * Used as int extra field in
+ * {@link com.trustedlogic.trustednfc.android.NfcManager#LLCP_LINK_STATE_CHANGED_ACTION}
+ * . It contains the new state of the LLCP link.
+ */
+ public static final String LLCP_LINK_STATE_CHANGED_EXTRA = "com.trustedlogic.trustednfc.android.extra.LLCP_LINK_STATE";
+
+ /**
+ * Broadcast Action: the LLCP link state changed.
+ * <p>
+ * Always contains the extra field
+ * {@link com.trustedlogic.trustednfc.android.NfcManager#LLCP_LINK_STATE_CHANGED_EXTRA}.
+ * <p class="note">
+ * <strong>Note:</strong> Requires the NFC_LLCP permission.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String LLCP_LINK_STATE_CHANGED_ACTION = "com.trustedlogic.trustednfc.android.action.LLCP_LINK_STATE_CHANGED";
+
+ private static final String TAG = "NfcManager";
+
+ private Handler mHandler;
+
+ private INfcManager mService;
+
+ private INfcTag mNfcTagService;
+
+ private IP2pTarget mP2pTargetService;
+
+ private IP2pInitiator mP2pInitiatorService;
+
+ private ILlcpSocket mLlcpSocketService;
+
+ private ILlcpConnectionlessSocket mLlcpConnectionlessSocketService;
+
+ private ILlcpServiceSocket mLlcpServiceSocketService;
+
+ static NfcException convertErrorToNfcException(int errorCode) {
+ return convertErrorToNfcException(errorCode, null);
+ }
+
+ static NfcException convertErrorToNfcException(int errorCode, String message) {
+ if (message == null) {
+ message = "";
+ } else {
+ message = " (" + message + ")";
+ }
+
+ switch (errorCode) {
+ case ErrorCodes.ERROR_BUSY:
+ return new NfcException("Another operation is already pending" + message);
+ case ErrorCodes.ERROR_CANCELLED:
+ return new NfcException("Operation cancelled" + message);
+ case ErrorCodes.ERROR_TIMEOUT:
+ return new NfcException("Operation timed out" + message);
+ case ErrorCodes.ERROR_SOCKET_CREATION:
+ return new NfcException("Error during the creation of an Llcp socket:" + message);
+ case ErrorCodes.ERROR_SAP_USED:
+ return new NfcException("Error SAP already used:" + message);
+ case ErrorCodes.ERROR_SERVICE_NAME_USED:
+ return new NfcException("Error Service Name already used:" + message);
+ case ErrorCodes.ERROR_SOCKET_OPTIONS:
+ return new NfcException("Error Socket options:" + message);
+ case ErrorCodes.ERROR_INVALID_PARAM:
+ return new NfcException("Error Set Properties: invalid param" + message);
+ case ErrorCodes.ERROR_NFC_ON:
+ return new NfcException("Error Set Properties : NFC is ON" + message);
+ case ErrorCodes.ERROR_NOT_INITIALIZED:
+ return new NfcException("NFC is not running " + message);
+ case ErrorCodes.ERROR_SE_ALREADY_SELECTED:
+ return new NfcException("Secure Element already connected" + message);
+ case ErrorCodes.ERROR_NO_SE_CONNECTED:
+ return new NfcException("No Secure Element connected" + message);
+ case ErrorCodes.ERROR_SE_CONNECTED:
+ return new NfcException("A secure Element is already connected" + message);
+ default:
+ return new NfcException("Unkown error code " + errorCode + message);
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public NfcManager(INfcManager service, Handler handler) {
+ mService = service;
+ mHandler = handler;
+ try {
+ mNfcTagService = mService.getNfcTagInterface();
+ mP2pInitiatorService = mService.getP2pInitiatorInterface();
+ mP2pTargetService = mService.getP2pTargetInterface();
+ mLlcpServiceSocketService = mService.getLlcpServiceInterface();
+ mLlcpConnectionlessSocketService = mService.getLlcpConnectionlessInterface();
+ mLlcpSocketService = mService.getLlcpInterface();
+ } catch (RemoteException e) {
+ mLlcpSocketService = null;
+ mNfcTagService = null;
+ mP2pInitiatorService = null;
+ mP2pTargetService = null;
+ mLlcpConnectionlessSocketService = null;
+ mLlcpServiceSocketService = null;
+ }
+ }
+
+ /**
+ * Return the status of the NFC feature
+ *
+ * @return mIsNfcEnabled
+ * @since AA02.01
+ */
+ public boolean isEnabled() {
+ try {
+ return mService.isEnabled();
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in isEnabled(): ", e);
+ return false;
+ }
+ }
+
+ /**
+ * Enable the NFC Feature
+ * <p class="note">
+ * <strong>Note:</strong> Requires the NFC_ADMIN permission
+ *
+ * @throws NfcException if the enable failed
+ * @since AA02.01
+ */
+ public void enable() throws NfcException {
+ try {
+ boolean isSuccess = mService.enable();
+ if (isSuccess == false) {
+ throw new NfcException("NFC Service failed to enable");
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in enable(): ", e);
+ }
+ }
+
+ /**
+ * Disable the NFC feature
+ * <p class="note">
+ * <strong>Note:</strong> Requires the NFC_ADMIN permission
+ *
+ * @throws NfcException if the disable failed
+ * @since AA02.01
+ */
+ public void disable() throws NfcException {
+ try {
+ boolean isSuccess = mService.disable();
+ if (isSuccess == false) {
+ throw new NfcException("NFC Service failed to disable");
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in disable(): ", e);
+ }
+ }
+
+ /**
+ * Get the list of the identifiers of the Secure Elements detected
+ * by the NFC controller.
+ *
+ * @return list a list of Secure Element identifiers.
+ * @see #getSelectedSecureElement
+ * @see #selectSecureElement(int)
+ * @see #deselectSecureElement
+ * @since AA02.01
+ */
+ public int[] getSecureElementList() {
+ try {
+ return mService.getSecureElementList();
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in getSecureElementList(): ", e);
+ return null;
+ }
+ }
+
+ /**
+ * Get the identifier of the currently selected secure element.
+ *
+ * @return id identifier of the currently selected Secure Element. 0 if none.
+ * @see #getSecureElementList
+ * @see #selectSecureElement(int)
+ * @see #deselectSecureElement
+ * @since AA02.01
+ */
+ public int getSelectedSecureElement() {
+ try {
+ return mService.getSelectedSecureElement();
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in getSelectedSecureElement(): ", e);
+ return -1;
+ }
+ }
+
+ /**
+ * Select a specific Secure Element by its identifier.
+ * <p class="note">
+ * <strong>Note:</strong> Requires the NFC_ADMIN permission
+ *
+ * @throws NfcException if a or this secure element is already selected
+ * @see #getSecureElementList
+ * @see #getSelectedSecureElement
+ * @see #deselectSecureElement
+ * @since AA02.01
+ */
+ public void selectSecureElement(int seId) throws NfcException {
+ try {
+ int status = mService.selectSecureElement(seId);
+ if(status != ErrorCodes.SUCCESS){
+ throw convertErrorToNfcException(status);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in selectSecureElement(): ", e);
+ }
+ }
+
+ /**
+ * Deselect the currently selected Secure Element
+ * <p class="note">
+ * <strong>Note:</strong> Requires the NFC_ADMIN permission
+ *
+ * @throws NfcException if no secure Element is selected
+ * @see #getSecureElementList
+ * @see #getSelectedSecureElement
+ * @see #selectSecureElement(int)
+ * @since AA02.01
+ */
+ public void deselectSecureElement() throws NfcException {
+ try {
+ int status = mService.deselectSecureElement();
+ if(status != ErrorCodes.SUCCESS){
+ throw convertErrorToNfcException(status);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in deselectSecureElement(): ", e);
+ }
+ }
+
+ /**
+ * Open a connection with a remote NFC peer
+ *
+ * This method does not return while no remote NFC peer enters the field.
+ * <p class="note">
+ * <strong>Note:</strong> Requires the NFC_RAW permission
+ *
+ * @return P2pDevice object to be used to communicate with the detected
+ * peer.
+ * @throws IOException if the target has been lost or the connection has
+ * been closed.
+ * @throws NfcException if an open is already started
+ * @see P2pDevice
+ * @see #getOpenTimeout
+ * @see #setOpenTimeout(int)
+ * @see #cancel
+ * @since AA02.01
+ */
+ public P2pDevice openP2pConnection() throws IOException, NfcException {
+ try {
+ int handle = mService.openP2pConnection();
+ // Handle potential errors
+ if (ErrorCodes.isError(handle)) {
+ if (handle == ErrorCodes.ERROR_IO) {
+ throw new IOException();
+ } else {
+ throw convertErrorToNfcException(handle);
+ }
+ }
+ // Build the public NfcTag object, depending on its type
+ if (mP2pTargetService.getMode(handle) == P2pDevice.MODE_P2P_TARGET) {
+ return new P2pTarget(mP2pTargetService, handle);
+ } else {
+ return new P2pInitiator(mP2pInitiatorService, handle);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in openTagConnection(): ", e);
+ return null;
+ }
+ }
+
+ /**
+ * Open a connection with a tag
+ *
+ * This method does not return while no tag enters the field.
+ * <p class="note">
+ * <strong>Note:</strong> Requires the NFC_RAW permission
+ *
+ * @return tag object to be use to communicate with the detected NfcTag.
+ * @throws IOException if the target has been lost or the connection has
+ * been closed.
+ * @throws NfcException if an open is already started
+ * @see NfcTag
+ * @see #getOpenTimeout
+ * @see #setOpenTimeout(int)
+ * @see #cancel
+ * @since AA02.01
+ */
+ public NfcTag openTagConnection() throws IOException, NfcException {
+ try {
+ int handle = mService.openTagConnection();
+ // Handle potential errors
+ if (ErrorCodes.isError(handle)) {
+ if (handle == ErrorCodes.ERROR_IO) {
+ throw new IOException();
+ } else {
+ throw convertErrorToNfcException(handle);
+ }
+ }
+ // Build the public NfcTag object
+ return new NfcTag(mNfcTagService, handle);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in openTagConnection(): ", e);
+ return null;
+ }
+ }
+
+ /**
+ * Set the timeout for open requests
+ * <p class="note">
+ * <strong>Note:</strong> Requires the NFC_RAW permission
+ *
+ * @param timeout value of the timeout for open request
+ * @see #openP2pConnection
+ * @see #openTagConnection
+ * @see #getOpenTimeout
+ * @since AA02.01
+ */
+ public void setOpenTimeout(int timeout) {
+ try {
+ mService.setOpenTimeout(timeout);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in setOpenTimeout(): ", e);
+ }
+ }
+
+ /**
+ * Get the timeout value of open requests
+ *
+ * @return mTimeout
+ * @see #setOpenTimeout(int)
+ * @since AA02.01
+ */
+ public int getOpenTimeout() {
+ try {
+ return mService.getOpenTimeout();
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in getOpenTimeout(): ", e);
+ return 0;
+ }
+ }
+
+ /**
+ * Cancel an openTagConnection or an openP2pConnection started
+ * <p class="note">
+ * <strong>Note:</strong> Requires the NFC_RAW permission
+ *
+ * @see #openP2pConnection
+ * @see #openTagConnection
+ * @since AA02.01
+ */
+ public void cancel() {
+ try {
+ mService.cancel();
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in cancel(): ", e);
+ }
+ }
+
+ /**
+ * Creates a connectionless socket for a LLCP link and set its Service
+ * Access Point number (SAP)
+ * <p class="note">
+ * <strong>Note:</strong> Requires the NFC_LLCP permission
+ *
+ * @param sap Service Access Point number related to the created
+ * Connectionless socket.
+ * @return LlcpConnectionlessSocket object to be used in a LLCP
+ * Connectionless communication.
+ * @throws IOException if the socket creation failed
+ * @throws NfcException if socket ressources are insufficicent
+ * @see LlcpConnectionlessSocket
+ * @since AA02.01
+ */
+ public LlcpConnectionlessSocket createLlcpConnectionlessSocket(int sap) throws IOException,
+ NfcException {
+
+ try {
+ int handle = mService.createLlcpConnectionlessSocket(sap);
+ // Handle potential errors
+ if (ErrorCodes.isError(handle)) {
+ if (handle == ErrorCodes.ERROR_IO) {
+ throw new IOException();
+ } else {
+ throw convertErrorToNfcException(handle);
+ }
+ }
+
+ // Build the public LlcpConnectionLess object
+ return new LlcpConnectionlessSocket(mLlcpConnectionlessSocketService, handle);
+
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in createLlcpConnectionlessSocket(): ", e);
+ return null;
+ }
+ }
+
+ /**
+ * Creates a LlcpServiceSocket for a LLCP link, set its Service Access Point
+ * number (SAP).
+ * <p>
+ * During a LLCP communication, the LlcpServiceSocket will create LlcpSocket
+ * to communicate with incoming LLCP clients. For that, a server socket need
+ * to have some informations as a working buffer length in order to handle
+ * incoming data and some options to define the LLCP communication.
+ * <p class="note">
+ * <strong>Note:</strong> Requires the NFC_LLCP permission
+ *
+ * @param sap
+ * @param sn Service Name of the LlcpServiceSocket
+ * @param miu Maximum Information Unit (MIU) for a LlcpSocket created by the
+ * LlcpServiceSocket
+ * @param rw Receive Window (RW) for a LlcpSocket created by the
+ * LlcpServiceSocket
+ * @param linearBufferLength size of the memory space needed to handle
+ * incoming data for every LlcpSocket created.
+ * @return LlcpServiceSocket object to be used as a LLCP Service in a
+ * connection oriented communication.
+ * @throws IOException if the socket creation failed
+ * @throws NfcException if socket ressources are insufficicent
+ * @see LlcpServiceSocket
+ * @since AA02.01
+ */
+ public LlcpServiceSocket createLlcpServiceSocket(int sap, String sn, int miu, int rw,
+ int linearBufferLength) throws IOException, NfcException {
+ try {
+ int handle = mService.createLlcpServiceSocket(sap, sn, miu, rw, linearBufferLength);
+ // Handle potential errors
+ if (ErrorCodes.isError(handle)) {
+ if (handle == ErrorCodes.ERROR_IO) {
+ throw new IOException();
+ } else {
+ throw convertErrorToNfcException(handle);
+ }
+ }
+
+ // Build the public LlcpServiceSocket object
+ return new LlcpServiceSocket(mLlcpServiceSocketService, mLlcpSocketService, handle);
+
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in createLlcpServiceSocket(): ", e);
+ return null;
+ }
+ }
+
+ /**
+ * Creates a LlcpSocket for a LLCP link with a specific Service Access Point
+ * number (SAP)
+ * <p>
+ * A LlcpSocket need to have a linear buffer in order to handle incoming
+ * data. This linear buffer will be used to store incoming data as a stream.
+ * Data will be readable later.
+ * <p class="note">
+ * <strong>Note:</strong> Requires the NFC_LLCP permission
+ *
+ * @param sap Service Access Point number for the created socket
+ * @param miu Maximum Information Unit (MIU) of the communication socket
+ * @param rw Receive Window (RW) of the communication socket
+ * @param linearBufferLength size of the memory space needed to handle
+ * incoming data with this socket
+ * @throws IOException if the socket creation failed
+ * @throws NfcException if socket ressources are insufficicent
+ * @see LlcpSocket
+ * @since AA02.01
+ */
+ public LlcpSocket createLlcpSocket(int sap, int miu, int rw, int linearBufferLength)
+ throws IOException, NfcException {
+ try {
+ int handle = mService.createLlcpSocket(sap, miu, rw, linearBufferLength);
+ // Handle potential errors
+ if (ErrorCodes.isError(handle)) {
+ if (handle == ErrorCodes.ERROR_IO) {
+ throw new IOException();
+ } else {
+ throw convertErrorToNfcException(handle);
+ }
+ }
+ // Build the public LlcpSocket object
+ return new LlcpSocket(mLlcpSocketService, handle);
+
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in createLlcpSocket(): ", e);
+ return null;
+ }
+ }
+
+ /**
+ * Set different parameters like the NCIP General bytes, the LLCP link
+ * parameters and all tag discovery parameters.
+ * <p class="note">
+ * <strong>Note:</strong> Requires the NFC_ADMIN permission
+ *
+ * @param param parameter to be updated with a new value
+ * @param value new value of the parameter
+ * @throws NfcException if incorrect parameters of NFC is ON
+ * @since AA02.01
+ */
+ public void setProperties(String param, String value) throws NfcException {
+ try {
+ int result = mService.setProperties(param, value);
+ // Handle potential errors
+ if (ErrorCodes.isError(result)) {
+ throw convertErrorToNfcException(result);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in setProperties(): ", e);
+ }
+ }
+
+ /**
+ * Get the value of different parameters like the NCFIP General bytes, the
+ * LLCP link parameters and all tag discovery parameters.
+ *
+ * @param param parameter to be updated
+ * @return String value of the requested parameter
+ * @throws RemoteException
+ * @since AA02.01
+ */
+ public String getProperties(String param) {
+ String value;
+ try {
+ value = mService.getProperties(param);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in getProperties(): ", e);
+ return null;
+ }
+ return value;
+ }
+
+}
diff --git a/core/java/com/trustedlogic/trustednfc/android/NfcTag.java b/core/java/com/trustedlogic/trustednfc/android/NfcTag.java
new file mode 100644
index 0000000..798c7e4
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/NfcTag.java
@@ -0,0 +1,250 @@
+/*
+ * 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.
+ */
+
+/**
+ * File : NFCTag.java
+ * Original-Author : Trusted Logic S.A. (Daniel Tomas)
+ * Created : 26-02-2010
+ */
+
+package com.trustedlogic.trustednfc.android;
+
+import java.io.IOException;
+
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.trustedlogic.trustednfc.android.internal.ErrorCodes;
+
+/**
+ * This class represents tags with no known formatting. One can use the method
+ * {@link #isNdef()} to determine if the tag can store NDEF-formatted messages.
+ * <p>
+ *
+ * <pre class="prettyprint">
+ * if (tag.isNdef()) {
+ * NdefTag ndefTag = (NdefTag) tag;
+ * NdefMessage msg = ndefTag.read();
+ * }
+ * </pre>
+ *
+ * @since AA01.04
+ * @see NdefMessage
+ * @hide
+ */
+public class NfcTag {
+
+ private static final String TAG = "NfcTag";
+
+ /**
+ * The handle returned by the NFC service and used to identify the tag in
+ * every call of this class.
+ *
+ * @hide
+ */
+ protected int mHandle;
+
+ /**
+ * The entry point for tag operations.
+ *
+ * @hide
+ */
+ protected INfcTag mService;
+
+ /**
+ * Flag set when the object is closed and thus not usable any more.
+ *
+ * @hide
+ */
+ protected boolean isClosed = false;
+
+ /**
+ * Flag set when the tag is connected.
+ *
+ * @hide
+ */
+ protected boolean isConnected = false;
+
+ /**
+ * Flag set when a check NDEF is performed.
+ *
+ * @hide
+ */
+ protected boolean isNdef = false;
+
+ /**
+ * Check if tag is still opened.
+ *
+ * @return data sent by the P2pInitiator.
+ * @throws NfcException if accessing a closed target.
+ *
+ * @hide
+ */
+ public void checkState() throws NfcException {
+ if (isClosed) {
+ throw new NfcException("Tag has been closed.");
+ }
+ if (!isConnected) {
+ throw new NfcException("Tag is not connected.");
+ }
+ }
+
+ /**
+ * Internal constructor for the NfcTag class.
+ *
+ * @param service The entry point to the Nfc Service for NfcTag class.
+ * @param handle The handle returned by the NFC service and used to identify
+ * the tag in subsequent calls.
+ * @hide
+ */
+ NfcTag(INfcTag service, int handle) {
+ this.mService = service;
+ this.mHandle = handle;
+ }
+
+ /**
+ * Connects to the tag. This shall be called prior to any other operation on
+ * the tag.
+ *
+ * @throws IOException if the tag has been lost or the connection has been
+ * closed.
+ * @throws nfcException if the tag is already in connected state.
+ */
+ public void connect() throws NfcException, IOException {
+ // Check state
+ if (isClosed) {
+ throw new NfcException("Tag has been closed.");
+ }
+ if (isConnected) {
+ throw new NfcException("Already connected");
+ }
+
+ // Perform connect
+ try {
+ int result = mService.connect(mHandle);
+ if (ErrorCodes.isError(result)) {
+ if (result == ErrorCodes.ERROR_IO) {
+ throw new IOException("Failed to connect");
+ }
+ else {
+ throw NfcManager.convertErrorToNfcException(result);
+ }
+ }
+ isConnected = true;
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in connect(): ", e);
+ }
+ }
+
+ /**
+ * Disconnects from the tag. This must be called so that other targets can
+ * be discovered. It restarts the NFC discovery loop.
+ *
+ * @throws NfcException if the tag is already in disconnected state or not connected
+ */
+ public void close() throws NfcException {
+ // Check state
+ checkState();
+
+ try {
+ mService.close(mHandle);
+ isClosed = true;
+ isConnected = false;
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in close(): ", e);
+ }
+ }
+
+ /**
+ * Exchanges raw data with the tag, whatever the tag type.
+ *
+ * To exchange APDUs with a ISO14443-4-compliant tag, the data parameter
+ * must be filled with the C-APDU (CLA, INS, P1, P2 [, ...]). The returned
+ * data consists of the R-APDU ([...,] SW1, SW2).
+ *
+ * @param data data to be sent to the tag
+ * @return data sent in response by the tag
+ * @throws IOException if the tag has been lost or the connection has been
+ * closed.
+ * @throws NfcException in case of failure within the stack
+ */
+ public byte[] transceive(byte[] data) throws IOException, NfcException {
+ // Check state
+ checkState();
+
+ // Perform transceive
+ try {
+ byte[] response = mService.transceive(mHandle, data);
+ if (response == null) {
+ throw new IOException("Transceive failed");
+ }
+ return response;
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in transceive(): ", e);
+ return null;
+ }
+ }
+
+ /**
+ * Checks whether tag is NDEF-compliant or not.
+ *
+ * @return true if the tag is NDEF-compliant, false otherwise
+ * @throws NfcException in case an error occurred when trying to determine
+ * whether the tag is NDEF-compliant
+ */
+ public boolean isNdef() throws NfcException {
+ // Check state
+ checkState();
+
+ // Perform Check Ndef
+ try {
+ isNdef = mService.isNdef(mHandle);
+ return isNdef;
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in isNdef(): ", e);
+ return false;
+ }
+ }
+
+ /**
+ * Returns target type. constants.
+ *
+ * @return tag type.
+ */
+ public String getType() {
+ try {
+ return mService.getType(mHandle);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in getType(): ", e);
+ return null;
+ }
+ }
+
+ /**
+ * Returns target UID.
+ *
+ * @return tag UID.
+ */
+ public byte[] getUid() {
+ try {
+ return mService.getUid(mHandle);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in getType(): ", e);
+ return null;
+ }
+ }
+
+}
diff --git a/core/java/com/trustedlogic/trustednfc/android/P2pDevice.java b/core/java/com/trustedlogic/trustednfc/android/P2pDevice.java
new file mode 100644
index 0000000..65800f2
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/P2pDevice.java
@@ -0,0 +1,89 @@
+/*
+ * 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.
+ */
+
+/**
+ * File : P2PDevice.java
+ * Original-Author : Trusted Logic S.A. (Daniel Tomas)
+ * Created : 26-02-2010
+ */
+
+package com.trustedlogic.trustednfc.android;
+
+import java.io.IOException;
+
+/**
+ * P2pDevice is the abstract base class for all supported P2P targets the
+ * NfcManager can handle.
+ * @hide
+ */
+public abstract class P2pDevice {
+
+ /**
+ * Peer-to-Peer Target.
+ */
+ public static final short MODE_P2P_TARGET = 0x00;
+
+ /**
+ * Peer-to-Peer Initiator.
+ */
+ public static final short MODE_P2P_INITIATOR = 0x01;
+
+ /**
+ * Invalid target type.
+ */
+ public static final short MODE_INVALID = 0xff;
+
+ /**
+ * Target handle, used by native calls.
+ * @hide
+ */
+ protected int mHandle;
+
+ /**
+ * Flag set when the object is closed and thus not usable any more.
+ * @hide
+ */
+ protected boolean isClosed = false;
+
+ /**
+ * Prevent default constructor to be public.
+ * @hide
+ */
+ protected P2pDevice() {
+ }
+
+ /**
+ * Returns the remote NFC-IP1 General Bytes.
+ *
+ * @return remote general bytes
+ * @throws IOException
+ */
+ public byte[] getGeneralBytes() throws IOException {
+ // Should not be called directly (use subclasses overridden method instead)
+ return null;
+ }
+
+ /**
+ * Returns target type. The value returned can be one of the TYPE_*
+ * constants.
+ *
+ * @return target type.
+ */
+ public int getMode() {
+ // Should not be called directly (use subclasses overridden method instead)
+ return MODE_INVALID;
+ }
+}
diff --git a/core/java/com/trustedlogic/trustednfc/android/P2pInitiator.java b/core/java/com/trustedlogic/trustednfc/android/P2pInitiator.java
new file mode 100644
index 0000000..0f28ae0
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/P2pInitiator.java
@@ -0,0 +1,115 @@
+/*
+ * 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.
+ */
+
+/**
+ * File : P2PInitiator.java
+ * Original-Author : Trusted Logic S.A. (Daniel Tomas)
+ */
+
+package com.trustedlogic.trustednfc.android;
+
+import java.io.IOException;
+
+import com.trustedlogic.trustednfc.android.internal.ErrorCodes;
+
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * P2pInitiator represents the initiator in an NFC-IP1 peer-to-peer
+ * communication.
+ *
+ * @see P2pTarget
+ * @since AA02.01
+ * @hide
+ */
+public class P2pInitiator extends P2pDevice {
+
+ private static final String TAG = "P2pInitiator";
+
+ /**
+ * The entry point for P2P tag operations.
+ * @hide
+ */
+ private IP2pInitiator mService;
+
+ /**
+ * Internal constructor for the P2pInitiator class.
+ *
+ * @param handle The handle returned by the NFC service and used to identify
+ * the tag in subsequent calls.
+ *
+ * @hide
+ */
+ P2pInitiator(IP2pInitiator service, int handle) {
+ this.mService = service;
+ this.mHandle = handle;
+ }
+
+ /**
+ * Receives data from a P2pInitiator.
+ *
+ * @return data sent by the P2pInitiator.
+ * @throws IOException if the target has been lost or if the connection has
+ * been closed.
+ */
+ public byte[] receive() throws IOException {
+ try {
+ byte[] result = mService.receive(mHandle);
+ if (result == null) {
+ throw new IOException("Tag has been lost");
+ }
+ return result;
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in receive(): ", e);
+ return null;
+ }
+ }
+
+ /**
+ * Sends data to a P2pInitiator.
+ *
+ * @param data data to be sent to the P2pInitiator.
+ * @throws IOException if the target has been lost or if the connection has
+ * been closed.
+ */
+ public void send(byte[] data) throws IOException {
+ try {
+ boolean isSuccess = mService.send(mHandle, data);
+ if (!isSuccess) {
+ throw new IOException("Tag has been lost");
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in send(): ", e);
+ }
+ }
+
+ @Override
+ public byte[] getGeneralBytes() {
+ try {
+ return mService.getGeneralBytes(mHandle);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in getGeneralBytes(): ", e);
+ return null;
+ }
+ }
+
+ @Override
+ public int getMode() {
+ return P2pDevice.MODE_P2P_INITIATOR;
+ }
+
+}
diff --git a/core/java/com/trustedlogic/trustednfc/android/P2pTarget.java b/core/java/com/trustedlogic/trustednfc/android/P2pTarget.java
new file mode 100644
index 0000000..b5e00db
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/P2pTarget.java
@@ -0,0 +1,183 @@
+/*
+ * 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.
+ */
+
+/**
+ * File : P2PTarget.java
+ * Original-Author : Trusted Logic S.A. (Daniel Tomas)
+ */
+
+package com.trustedlogic.trustednfc.android;
+
+import java.io.IOException;
+
+import com.trustedlogic.trustednfc.android.internal.ErrorCodes;
+
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * P2pTarget represents the target in an NFC-IP1 peer-to-peer communication.
+ *
+ * @see P2pInitiator
+ * @since AA02.01
+ * @hide
+ */
+public class P2pTarget extends P2pDevice {
+
+ private static final String TAG = "P2pTarget";
+
+ /**
+ * The entry point for P2P tag operations.
+ * @hide
+ */
+ private IP2pTarget mService;
+
+ /**
+ * Flag set when the object is closed and thus not usable any more.
+ * @hide
+ */
+ private boolean isClosed = false;
+
+ /**
+ * Flag set when the tag is connected.
+ * @hide
+ */
+ private boolean isConnected = false;
+
+ /**
+ * Check if tag is still opened.
+ *
+ * @return data sent by the P2pInitiator.
+ * @throws NfcException if accessing a closed target.
+ *
+ * @hide
+ */
+ public void checkState() throws NfcException {
+ if(isClosed) {
+ throw new NfcException("Tag has been closed.");
+ }
+ }
+
+ /**
+ * Internal constructor for the P2pTarget class.
+ *
+ * @param handle The handle returned by the NFC service and used to identify
+ * the tag in subsequent calls.
+ *
+ * @hide
+ */
+ P2pTarget(IP2pTarget service, int handle) {
+ this.mService = service;
+ this.mHandle = handle;
+ }
+
+ /**
+ * Connects to the P2pTarget. This shall be called prior to any other
+ * operation on the P2pTarget.
+ *
+ * @throws NfcException
+ */
+ public void connect() throws NfcException {
+ // Check state
+ checkState();
+ if (isConnected) {
+ throw new NfcException("Already connected");
+ }
+
+ // Perform connect
+ try {
+ int result = mService.connect(mHandle);
+ if (ErrorCodes.isError(result)) {
+ if (result == ErrorCodes.ERROR_IO) {
+ throw new NfcException("Failed to connect");
+ }
+ else {
+ throw NfcManager.convertErrorToNfcException(result);
+ }
+ }
+ isConnected = true;
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in connect(): ", e);
+ }
+ }
+
+ /**
+ * Disconnects from the P2p Target. This must be called so that other
+ * targets can be discovered. It restarts the NFC discovery loop.
+ *
+ * @throws NFCException
+ */
+ public void disconnect() throws NfcException {
+ checkState();
+ try {
+ mService.disconnect(mHandle);
+ isConnected = true;
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in disconnect(): ", e);
+ }
+ }
+
+ /**
+ * Exchanges raw data with the P2pTarget.
+ *
+ * @param data data to be sent to the P2pTarget
+ * @return data sent in response by the P2pTarget
+ * @throws IOException if the target has been lost or the connection has
+ * been closed.
+ * @throws NfcException in case of failure within the stack
+ */
+ public byte[] transceive(byte[] data) throws IOException, NfcException {
+ // Check state
+ checkState();
+
+ // Perform transceive
+ try {
+ byte[] response = mService.transceive(mHandle, data);
+ if (response == null) {
+ throw new IOException("Transceive failed");
+ }
+ return response;
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in transceive(): ", e);
+ return null;
+ }
+ }
+
+ /**
+ * Get the General bytes of the connected P2P Target
+ *
+ * @return general bytes of the connected P2P Target
+ * @throws IOException if the target in not in connected state
+ */
+ public byte[] getGeneralBytes() throws IOException {
+ try {
+ if(isConnected){
+ return mService.getGeneralBytes(mHandle);
+ }else{
+ throw new IOException("Target not in connected state");
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in getGeneralBytes(): ", e);
+ return null;
+ }
+ }
+
+ @Override
+ public int getMode() {
+ return P2pDevice.MODE_P2P_TARGET;
+ }
+
+}
diff --git a/core/java/com/trustedlogic/trustednfc/android/internal/ErrorCodes.java b/core/java/com/trustedlogic/trustednfc/android/internal/ErrorCodes.java
new file mode 100644
index 0000000..ca3b7e0
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/internal/ErrorCodes.java
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+
+/**
+ * File : ErrorCodes.java
+ * Original-Author : Trusted Logic S.A. (Sylvain Fonteneau)
+ * Created : 26-02-2010
+ */
+
+package com.trustedlogic.trustednfc.android.internal;
+
+/**
+ * This class defines all the error codes that can be returned by the service
+ * and producing an exception on the application level. These are needed since
+ * binders does not support exceptions.
+ *
+ * @hide
+ */
+public class ErrorCodes {
+
+ public static boolean isError(int code) {
+ if (code < 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public static final int SUCCESS = 0;
+
+ public static final int ERROR_IO = -1;
+
+ public static final int ERROR_CANCELLED = -2;
+
+ public static final int ERROR_TIMEOUT = -3;
+
+ public static final int ERROR_BUSY = -4;
+
+ public static final int ERROR_CONNECT = -5;
+
+ public static final int ERROR_DISCONNECT = -5;
+
+ public static final int ERROR_READ = -6;
+
+ public static final int ERROR_WRITE = -7;
+
+ public static final int ERROR_INVALID_PARAM = -8;
+
+ public static final int ERROR_INSUFFICIENT_RESOURCES = -9;
+
+ public static final int ERROR_SOCKET_CREATION = -10;
+
+ public static final int ERROR_SOCKET_NOT_CONNECTED = -11;
+
+ public static final int ERROR_BUFFER_TO_SMALL = -12;
+
+ public static final int ERROR_SAP_USED = -13;
+
+ public static final int ERROR_SERVICE_NAME_USED = -14;
+
+ public static final int ERROR_SOCKET_OPTIONS = -15;
+
+ public static final int ERROR_NFC_ON = -16;
+
+ public static final int ERROR_NOT_INITIALIZED = -17;
+
+ public static final int ERROR_SE_ALREADY_SELECTED = -18;
+
+ public static final int ERROR_SE_CONNECTED = -19;
+
+ public static final int ERROR_NO_SE_CONNECTED = -20;
+
+
+
+
+
+
+}
diff --git a/core/java/com/trustedlogic/trustednfc/android/internal/NativeLlcpConnectionlessSocket.java b/core/java/com/trustedlogic/trustednfc/android/internal/NativeLlcpConnectionlessSocket.java
new file mode 100644
index 0000000..ccfbeb4
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/internal/NativeLlcpConnectionlessSocket.java
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+
+/**
+ * File : NativeLlcpConnectionLessSocket.java
+ * Original-Author : Trusted Logic S.A. (Sylvain Fonteneau)
+ * Created : 18-02-2010
+ */
+
+package com.trustedlogic.trustednfc.android.internal;
+
+import com.trustedlogic.trustednfc.android.LlcpPacket;
+
+/**
+ * LlcpConnectionlessSocket represents a LLCP Connectionless object to be used
+ * in a connectionless communication
+ *
+ * @since AA02.01
+ * {@hide}
+ */
+
+public class NativeLlcpConnectionlessSocket {
+
+ private int mHandle;
+
+ private int mSap;
+
+ private int mLinkMiu;
+
+ public NativeLlcpConnectionlessSocket(){;
+ }
+
+ public NativeLlcpConnectionlessSocket(int sap){
+ mSap = sap;
+ }
+
+ public native boolean doSendTo(int sap, byte[] data);
+
+ public native LlcpPacket doReceiveFrom(int linkMiu);
+
+ public native boolean doClose();
+
+ public int getLinkMiu(){
+ return mLinkMiu;
+ }
+
+ public int getSap(){
+ return mSap;
+ }
+
+ public int getHandle(){
+ return mHandle;
+ }
+
+}
diff --git a/core/java/com/trustedlogic/trustednfc/android/internal/NativeLlcpServiceSocket.java b/core/java/com/trustedlogic/trustednfc/android/internal/NativeLlcpServiceSocket.java
new file mode 100644
index 0000000..a01f135
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/internal/NativeLlcpServiceSocket.java
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+/**
+ * File : NativeLlcpServerSocket.java
+ * Original-Author : Trusted Logic S.A. (Sylvain Fonteneau)
+ * Created : 18-02-2010
+ */
+
+package com.trustedlogic.trustednfc.android.internal;
+
+/**
+ * LlcpServiceSocket represents a LLCP Service to be used in a
+ * Connection-oriented communication
+ * {@hide}
+ */
+
+public class NativeLlcpServiceSocket {
+
+ private int mHandle;
+
+ private int mLocalMiu;
+
+ private int mLocalRw;
+
+ private int mLocalLinearBufferLength;
+
+ private int mSap;
+
+ private int mTimeout;
+
+ private String mServiceName;
+
+ public NativeLlcpServiceSocket(){
+
+ }
+
+ public NativeLlcpServiceSocket(String serviceName){
+ mServiceName = serviceName;
+ }
+
+ public native NativeLlcpSocket doAccept(int timeout, int miu, int rw, int linearBufferLength);
+
+ public native boolean doClose();
+
+ public int getHandle(){
+ return mHandle;
+ }
+
+ public void setAcceptTimeout(int timeout){
+ mTimeout = timeout;
+ }
+
+ public int getAcceptTimeout(){
+ return mTimeout;
+ }
+
+ public int getRw(){
+ return mLocalRw;
+ }
+
+ public int getMiu(){
+ return mLocalMiu;
+ }
+
+ public int getLinearBufferLength(){
+ return mLocalLinearBufferLength;
+ }
+}
diff --git a/core/java/com/trustedlogic/trustednfc/android/internal/NativeLlcpSocket.java b/core/java/com/trustedlogic/trustednfc/android/internal/NativeLlcpSocket.java
new file mode 100644
index 0000000..077c5e0
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/internal/NativeLlcpSocket.java
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ */
+
+/**
+ * File : NativeLlcpClientSocket.java
+ * Original-Author : Trusted Logic S.A. (Sylvain Fonteneau)
+ * Created : 18-02-2010
+ */
+
+package com.trustedlogic.trustednfc.android.internal;
+
+/**
+ * LlcpClientSocket represents a LLCP Connection-Oriented client to be used in a
+ * connection-oriented communication
+ * {@hide}
+ */
+
+public class NativeLlcpSocket {
+
+ private int mHandle;
+
+ private int mSap;
+
+ private int mLocalMiu;
+
+ private int mLocalRw;
+
+ private int mTimeout;
+
+ public NativeLlcpSocket(){
+
+ }
+
+ public NativeLlcpSocket(int sap, int miu, int rw){
+ mSap = sap;
+ mLocalMiu = miu;
+ mLocalRw = rw;
+ }
+
+ public native boolean doConnect(int nSap, int timeout);
+
+ public native boolean doConnectBy(String sn, int timeout);
+
+ public native boolean doClose();
+
+ public native boolean doSend(byte[] data);
+
+ public native int doReceive(byte[] recvBuff);
+
+ public native int doGetRemoteSocketMiu();
+
+ public native int doGetRemoteSocketRw();
+
+
+
+ public void setConnectTimeout(int timeout){
+ mTimeout = timeout;
+ }
+
+ public int getConnectTimeout(){
+ return mTimeout;
+ }
+
+ public int getSap(){
+ return mSap;
+ }
+
+ public int getMiu(){
+ return mLocalMiu;
+ }
+
+ public int getRw(){
+ return mLocalRw;
+ }
+
+ public int getHandle(){
+ return mHandle;
+ }
+
+}
diff --git a/core/java/com/trustedlogic/trustednfc/android/internal/NativeNdefTag.java b/core/java/com/trustedlogic/trustednfc/android/internal/NativeNdefTag.java
new file mode 100644
index 0000000..d1e64a6
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/internal/NativeNdefTag.java
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+/**
+ * File : NativeNdefTag.java
+ * Original-Author : Trusted Logic S.A. (Sylvain Fonteneau)
+ * Created : 18-02-2010
+ */
+
+package com.trustedlogic.trustednfc.android.internal;
+
+/**
+ * Native interface to the NDEF tag functions
+ *
+ * {@hide}
+ */
+public class NativeNdefTag {
+ private int mHandle;
+
+ public native byte[] doRead();
+
+ public native boolean doWrite(byte[] buf);
+}
diff --git a/core/java/com/trustedlogic/trustednfc/android/internal/NativeNfcManager.java b/core/java/com/trustedlogic/trustednfc/android/internal/NativeNfcManager.java
new file mode 100644
index 0000000..2f5a0f0
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/internal/NativeNfcManager.java
@@ -0,0 +1,325 @@
+/*
+ * 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.
+ */
+
+/**
+ * File : NativeNfcManager.java
+ * Original-Author : Trusted Logic S.A. (Sylvain Fonteneau)
+ * Created : 18-02-2010
+ */
+
+package com.trustedlogic.trustednfc.android.internal;
+
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Log;
+
+import com.trustedlogic.trustednfc.android.NfcManager;
+import com.trustedlogic.trustednfc.android.NdefMessage;
+import com.trustedlogic.trustednfc.android.NfcTag;
+
+/**
+ * Native interface to the NFC Manager functions {@hide}
+ */
+public class NativeNfcManager {
+
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String INTERNAL_LLCP_LINK_STATE_CHANGED_EXTRA = "com.trustedlogic.trustednfc.android.extra.INTERNAL_LLCP_LINK_STATE";
+
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String INTERNAL_LLCP_LINK_STATE_CHANGED_ACTION = "com.trustedlogic.trustednfc.android.action.INTERNAL_LLCP_LINK_STATE_CHANGED";
+
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String INTERNAL_TARGET_DESELECTED_ACTION = "com.trustedlogic.trustednfc.android.action.INTERNAL_TARGET_DESELECTED";
+
+ /* Native structure */
+ private int mNative;
+
+ private Context mContext;
+
+ private Handler mNfcHandler;
+
+ private static final String TAG = "NativeNfcManager";
+
+ private static final int MSG_NDEF_TAG = 0;
+
+ private static final int MSG_CARD_EMULATION = 1;
+
+ private static final int MSG_LLCP_LINK_ACTIVATION = 2;
+
+ private static final int MSG_LLCP_LINK_DEACTIVATED = 3;
+
+ private static final int MSG_TARGET_DESELECTED = 4;
+
+ public NativeNfcManager(Context context) {
+ mNfcHandler = new NfcHandler();
+ mContext = context;
+ }
+
+ /**
+ * Initializes Native structure
+ */
+ public native boolean initializeNativeStructure();
+
+ /**
+ * Initializes NFC stack.
+ */
+ public native boolean initialize();
+
+ /**
+ * Deinitializes NFC stack.
+ */
+ public native boolean deinitialize();
+
+ /**
+ * Enable discory for the NdefMessage and Transaction notification
+ */
+ public native void enableDiscovery(int mode);
+
+ /**
+ * Disables an NFCManager mode of operation. Allows to disable tag reader,
+ * peer to peer initiator or target modes.
+ *
+ * @param mode discovery mode to enable. Must be one of the provided
+ * NFCManager.DISCOVERY_MODE_* constants.
+ */
+ public native void disableDiscoveryMode(int mode);
+
+ public native int[] doGetSecureElementList();
+
+ public native void doSelectSecureElement(int seID);
+
+ public native void doDeselectSecureElement(int seID);
+
+ public native NativeP2pDevice doOpenP2pConnection(int timeout);
+
+ public native NativeNfcTag doOpenTagConnection(int timeout);
+
+ public native int doGetLastError();
+
+ public native void doSetProperties(int param, int value);
+
+ public native void doCancel();
+
+ public native NativeLlcpConnectionlessSocket doCreateLlcpConnectionlessSocket(int nSap);
+
+ public native NativeLlcpServiceSocket doCreateLlcpServiceSocket(int nSap, String sn, int miu,
+ int rw, int linearBufferLength);
+
+ public native NativeLlcpSocket doCreateLlcpSocket(int sap, int miu, int rw,
+ int linearBufferLength);
+
+ public native boolean doCheckLlcp();
+
+ public native boolean doActivateLlcp();
+
+ private class NfcHandler extends Handler {
+ @Override
+ public void handleMessage(Message msg) {
+
+ try {
+ switch (msg.what) {
+ case MSG_NDEF_TAG:
+ Log.d(TAG, "Checking for NDEF tag message");
+ NativeNfcTag tag = (NativeNfcTag) msg.obj;
+ if (tag.doConnect()) {
+ if (tag.checkNDEF()) {
+ byte[] buff = tag.doRead();
+ if (buff != null) {
+ NdefMessage msgNdef = new NdefMessage(buff);
+ if (msgNdef != null) {
+ /* Send broadcast ordered */
+ Intent NdefMessageIntent = new Intent();
+ NdefMessageIntent
+ .setAction(NfcManager.NDEF_TAG_DISCOVERED_ACTION);
+ NdefMessageIntent.putExtra(NfcManager.NDEF_MESSAGE_EXTRA,
+ msgNdef);
+ Log.d(TAG, "NDEF message found, broadcasting to applications");
+ mContext.sendOrderedBroadcast(NdefMessageIntent,
+ android.Manifest.permission.NFC_NOTIFY);
+ /* Disconnect tag */
+ tag.doAsyncDisconnect();
+ }
+ } else {
+ Log.w(TAG, "Unable to read NDEF message (tag empty or not well formated)");
+ /* Disconnect tag */
+ tag.doAsyncDisconnect();
+ }
+ } else {
+ Log.d(TAG, "Tag is *not* NDEF compliant");
+ /* Disconnect tag */
+ tag.doAsyncDisconnect();
+ }
+ } else {
+ /* Disconnect tag */
+ tag.doAsyncDisconnect();
+ }
+ break;
+ case MSG_CARD_EMULATION:
+ Log.d(TAG, "Card Emulation message");
+ byte[] aid = (byte[]) msg.obj;
+ /* Send broadcast ordered */
+ Intent TransactionIntent = new Intent();
+ TransactionIntent.setAction(NfcManager.TRANSACTION_DETECTED_ACTION);
+ TransactionIntent.putExtra(NfcManager.AID_EXTRA, aid);
+ Log.d(TAG, "Broadcasting Card Emulation event");
+ mContext.sendOrderedBroadcast(TransactionIntent,
+ android.Manifest.permission.NFC_NOTIFY);
+ break;
+
+ case MSG_LLCP_LINK_ACTIVATION:
+ NativeP2pDevice device = (NativeP2pDevice) msg.obj;
+
+ Log.d(TAG, "LLCP Activation message");
+
+ if (device.getMode() == NativeP2pDevice.MODE_P2P_TARGET) {
+ if (device.doConnect()) {
+ /* Check Llcp compliancy */
+ if (doCheckLlcp()) {
+ /* Activate Llcp Link */
+ if (doActivateLlcp()) {
+ Log.d(TAG, "Initiator Activate LLCP OK");
+ /* Broadcast Intent Link LLCP activated */
+ Intent LlcpLinkIntent = new Intent();
+ LlcpLinkIntent
+ .setAction(INTERNAL_LLCP_LINK_STATE_CHANGED_ACTION);
+ LlcpLinkIntent.putExtra(
+ INTERNAL_LLCP_LINK_STATE_CHANGED_EXTRA,
+ NfcManager.LLCP_LINK_STATE_ACTIVATED);
+ Log.d(TAG, "Broadcasting internal LLCP activation");
+ mContext.sendBroadcast(LlcpLinkIntent);
+ }
+
+ } else {
+ device.doDisconnect();
+ }
+
+ }
+
+ } else if (device.getMode() == NativeP2pDevice.MODE_P2P_INITIATOR) {
+ /* Check Llcp compliancy */
+ if (doCheckLlcp()) {
+ /* Activate Llcp Link */
+ if (doActivateLlcp()) {
+ Log.d(TAG, "Target Activate LLCP OK");
+ /* Broadcast Intent Link LLCP activated */
+ Intent LlcpLinkIntent = new Intent();
+ LlcpLinkIntent
+ .setAction(INTERNAL_LLCP_LINK_STATE_CHANGED_ACTION);
+ LlcpLinkIntent.putExtra(INTERNAL_LLCP_LINK_STATE_CHANGED_EXTRA,
+ NfcManager.LLCP_LINK_STATE_ACTIVATED);
+ Log.d(TAG, "Broadcasting internal LLCP activation");
+ mContext.sendBroadcast(LlcpLinkIntent);
+ }
+ }
+ }
+ break;
+
+ case MSG_LLCP_LINK_DEACTIVATED:
+ /* Broadcast Intent Link LLCP activated */
+ Log.d(TAG, "LLCP Link Deactivated message");
+ Intent LlcpLinkIntent = new Intent();
+ LlcpLinkIntent.setAction(NfcManager.LLCP_LINK_STATE_CHANGED_ACTION);
+ LlcpLinkIntent.putExtra(NfcManager.LLCP_LINK_STATE_CHANGED_EXTRA,
+ NfcManager.LLCP_LINK_STATE_DEACTIVATED);
+ Log.d(TAG, "Broadcasting LLCP deactivation");
+ mContext.sendOrderedBroadcast(LlcpLinkIntent,
+ android.Manifest.permission.NFC_LLCP);
+ break;
+
+ case MSG_TARGET_DESELECTED:
+ /* Broadcast Intent Target Deselected */
+ Log.d(TAG, "Target Deselected");
+ Intent TargetDeselectedIntent = new Intent();
+ TargetDeselectedIntent.setAction(INTERNAL_TARGET_DESELECTED_ACTION);
+ Log.d(TAG, "Broadcasting Intent");
+ mContext.sendOrderedBroadcast(TargetDeselectedIntent,
+ android.Manifest.permission.NFC_LLCP);
+ break;
+
+ default:
+ Log.e(TAG, "Unknown message received");
+ break;
+ }
+ } catch (Exception e) {
+ // Log, don't crash!
+ Log.e(TAG, "Exception in NfcHandler.handleMessage:", e);
+ }
+ }
+ };
+
+ /**
+ * Notifies Ndef Message
+ */
+ private void notifyNdefMessageListeners(NativeNfcTag tag) {
+ Message msg = mNfcHandler.obtainMessage();
+
+ msg.what = MSG_NDEF_TAG;
+ msg.obj = tag;
+
+ mNfcHandler.sendMessage(msg);
+ }
+
+ /**
+ * Notifies transaction
+ */
+ private void notifyTargetDeselected() {
+ Message msg = mNfcHandler.obtainMessage();
+
+ msg.what = MSG_TARGET_DESELECTED;
+
+ mNfcHandler.sendMessage(msg);
+ }
+
+ /**
+ * Notifies transaction
+ */
+ private void notifyTransactionListeners(byte[] aid) {
+ Message msg = mNfcHandler.obtainMessage();
+
+ msg.what = MSG_CARD_EMULATION;
+ msg.obj = aid;
+
+ mNfcHandler.sendMessage(msg);
+ }
+
+ /**
+ * Notifies P2P Device detected, to activate LLCP link
+ */
+ private void notifyLlcpLinkActivation(NativeP2pDevice device) {
+ Message msg = mNfcHandler.obtainMessage();
+
+ msg.what = MSG_LLCP_LINK_ACTIVATION;
+ msg.obj = device;
+
+ mNfcHandler.sendMessage(msg);
+ }
+
+ /**
+ * Notifies P2P Device detected, to activate LLCP link
+ */
+ private void notifyLlcpLinkDeactivated() {
+ Message msg = mNfcHandler.obtainMessage();
+
+ msg.what = MSG_LLCP_LINK_DEACTIVATED;
+
+ mNfcHandler.sendMessage(msg);
+ }
+
+}
diff --git a/core/java/com/trustedlogic/trustednfc/android/internal/NativeNfcTag.java b/core/java/com/trustedlogic/trustednfc/android/internal/NativeNfcTag.java
new file mode 100644
index 0000000..b92783d
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/internal/NativeNfcTag.java
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+/**
+ * File : NativeNfcTag.java
+ * Original-Author : Trusted Logic S.A. (Sylvain Fonteneau)
+ * Created : 18-02-2010
+ */
+
+package com.trustedlogic.trustednfc.android.internal;
+
+/**
+ * Native interface to the NFC tag functions
+ *
+ * {@hide}
+ */
+public class NativeNfcTag {
+ private int mHandle;
+
+ private String mType;
+
+ private byte[] mUid;
+
+ public native boolean doConnect();
+
+ public native boolean doDisconnect();
+
+ public native void doAsyncDisconnect();
+
+ public native byte[] doTransceive(byte[] data);
+
+ public native boolean checkNDEF();
+
+ public native byte[] doRead();
+
+ public native boolean doWrite(byte[] buf);
+
+ public int getHandle() {
+ return mHandle;
+ }
+
+ public String getType() {
+ return mType;
+ }
+
+ public byte[] getUid() {
+ return mUid;
+ }
+}
diff --git a/core/java/com/trustedlogic/trustednfc/android/internal/NativeP2pDevice.java b/core/java/com/trustedlogic/trustednfc/android/internal/NativeP2pDevice.java
new file mode 100644
index 0000000..75d25ba
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/internal/NativeP2pDevice.java
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+/**
+ * File : NativeP2pDevice.java
+ * Original-Author : Trusted Logic S.A. (Sylvain Fonteneau)
+ * Created : 18-02-2010
+ */
+
+package com.trustedlogic.trustednfc.android.internal;
+
+/**
+ * Native interface to the P2P Initiator functions
+ *
+ * {@hide}
+ */
+public class NativeP2pDevice {
+
+ /**
+ * Peer-to-Peer Target.
+ */
+ public static final short MODE_P2P_TARGET = 0x00;
+
+ /**
+ * Peer-to-Peer Initiator.
+ */
+ public static final short MODE_P2P_INITIATOR = 0x01;
+
+ /**
+ * Invalid target type.
+ */
+ public static final short MODE_INVALID = 0xff;
+
+ private int mHandle;
+
+ private int mMode;
+
+ private byte[] mGeneralBytes;
+
+ public native byte[] doReceive();
+
+ public native boolean doSend(byte[] data);
+
+ public native boolean doConnect();
+
+ public native boolean doDisconnect();
+
+ public native byte[] doTransceive(byte[] data);
+
+ public int getHandle() {
+ return mHandle;
+ }
+
+ public int getMode() {
+ return mMode;
+ }
+
+ public byte[] getGeneralBytes() {
+ return mGeneralBytes;
+ }
+
+}
diff --git a/core/java/com/trustedlogic/trustednfc/android/package.html b/core/java/com/trustedlogic/trustednfc/android/package.html
new file mode 100644
index 0000000..0c0b605
--- /dev/null
+++ b/core/java/com/trustedlogic/trustednfc/android/package.html
@@ -0,0 +1,473 @@
+<html>
+<body>
+
+<p>Provides classes that manage the NFC functionality.</p>
+
+<p>The NFC functionality is related to Near Field Communication.</p>
+
+<p>The NFC APIs let applications:</p>
+<ul>
+ <li>Scan for remote NFC targets (NFC Tag or NFC Peer)</li>
+ <li>Transfer raw data to and from remote NFC targets (NFC Tags or NFC Peer)</li>
+ <li>Read/Write NDEF data from/to remote NFC targets (NFC Tags)</li>
+ <li>Establish LLCP connection with a remote NFC target (NFC Peer with LLCP support)</li>
+ <li>Exchange data with a remote NFC target through LLCP services (NFC Peer with LLCP support)</li>
+ <li>Be notified of transactions on the local Secure Element by an external NFC reader</li>
+</ul>
+
+
+<h1>Setting Up NFC</h1>
+
+<p>
+Before an application can use the NFC feature, it needs to check if NFC is
+supported on the device by getting an instance of the
+{@link com.trustedlogic.trustednfc.android.NfcManager} class.
+</p>
+
+<pre>
+ NfcManager mNfcManager = (NfcManager) getSystemService(Context.NFC_SERVICE);
+ if (mNfcManager == null) {
+ // Device does not support NFC
+ }
+</pre>
+
+<p>
+An application can ensure that NFC is enabled.
+If not, an application with the needed permission can request that NFC be
+enabled.
+</p>
+
+<pre>
+ if (!mNfcManager.isEnabled) {
+ // NFC is currently disabled.
+ // Enable NFC.
+ mNfcManager.enable();
+ }
+</pre>
+
+<p>
+Before using the card emulation mode, an application can ensure that a secure
+element is selected ({@link com.trustedlogic.trustednfc.android.NfcManager#getSelectedSecureElement}).
+If not, an application with the needed permission can recover the list of
+available secure elements on the device
+({@link com.trustedlogic.trustednfc.android.NfcManager#getSecureElementList}) and select one
+({@link com.trustedlogic.trustednfc.android.NfcManager#selectSecureElement}).
+</p>
+
+<p>
+Before using the NFC feature, an application can configure the NFC device by
+calling {@link com.trustedlogic.trustednfc.android.NfcManager#setProperties}. This function allows:
+</p>
+<ul>
+ <li>Enabling/disabling the NFC device capabilities (RF types, baudrates,
+ NFCIP-1 mode and role...)</li>
+ <li>Settings the NFCIP-1 general bytes and the LLCP link parameters</li>
+</ul>
+<p>
+The setting properties can be customized according to the Device capabilities.
+The next table give the minimal set of properties supported by the Device.
+Depending on the implementation, the table may be completed.
+</p>
+<table>
+ <TR><TH> Property Name </TH><TH> Property Values </TH></TR>
+ <TR><TD> discovery.felica </TD><TD> <b>true</b>|false </TD></TR>
+ <TR><TD> discovery.iso14443A </TD><TD> <b>true</b>|false </TD></TR>
+ <TR><TD> discovery.iso14443B </TD><TD> <b>true</b>|false </TD></TR>
+ <TR><TD> discovery.iso15693 </TD><TD> <b>true</b>|false </TD></TR>
+ <TR><TD> discovery.nfcip </TD><TD> <b>true</b>|false </TD></TR>
+ <TR><TD> nfcip.baudrate </TD><TD> 106|212|424 </TD></TR>
+ <TR><TD> nfcip.generalbytes </TD><TD> </TD></TR>
+ <TR><TD> nfcip.mode </TD><TD> active|passive|<b>all</b> </TD></TR>
+ <TR><TD> nfcip.role </TD><TD> initiator|target|<b>both</b> </TD></TR>
+ <TR><TD> llcp.lto </TD><TD> <b>150</b> (0 to 255) </TD></TR>
+ <TR><TD> llcp.opt </TD><TD> <b>0</b> (0 to 3) </TD></TR>
+ <TR><TD> llcp.miu </TD><TD> <b>128</b> (128 to 2176) </TD></TR>
+ <TR><TD> llcp.wks </TD><TD> <b>1</b> (0 to 15) </TD></TR>
+</table>
+<p>(default values in bold)</p>
+
+
+<h1>NFC Permissions</h1>
+
+<p>
+To change the NFC service settings such as enabling the NFC targets
+discovery or activating the secure element, an application must declare the
+NFC_ADMIN permission.
+</p>
+<p>
+To perform NFC raw communication with a remote NFC target in
+Reader/Write Mode or Peer-to-Peer Mode, an application must declare the NFC_RAW
+permission.
+</p>
+<p>
+To receive NDEF message or Secure Element intents, an application must declare
+the NFC_NOTIFY permission.
+</p>
+<p>
+To receive the LLCP link intent and perform an LLCP communication with a remote NFC target, an application must
+declare the NFC_LLCP permission.
+</p>
+
+
+<h1>NFC Usage</h1>
+
+<p>
+The following code samples illustrate the APIs usage regarding the NFC service
+use cases.
+</p>
+
+<h2>Reader/Writer Mode NDEF message notification</h2>
+
+<p>
+This code sample illustrates the NDEF message notification through an Intent declared in the manifest and a receiver implemented in the application.
+</p>
+<p>Main involved classes/methods:</p>
+
+<p>Manifest Example:</p>
+<pre>
+ <receiver android:name=".NfcReaderDemoReceiver">
+ <intent-filter>
+ <action android:name= "com.trustedlogic.trustednfc.android.action.NDEF_TAG_DISCOVERED"/>
+ </intent-filter>
+ </receiver>
+</pre>
+
+<p>Receiver Example:</p>
+<ul>
+ <li>{@link com.trustedlogic.trustednfc.android.NdefMessage}</li>
+ <li>{@link com.trustedlogic.trustednfc.android.NfcManager#NDEF_TAG_DISCOVERED_ACTION}</li>
+ <li>{@link com.trustedlogic.trustednfc.android.NfcManager#NDEF_MESSAGE_EXTRA}</li>
+</ul>
+<pre>
+public class NdefMessageReceiverSample extends BroadcastReceiver {
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(NfcManager.NDEF_TAG_DISCOVERERD_ACTION)) {
+ NdefMessage msg = intent.getParcelableExtra(NfcManager.NDEF_MESSAGE_EXTRA);
+
+ /* Manage the NdefMessage received */
+ }
+</pre>
+
+<h2>Reader/Writer Mode raw exchange</h2>
+
+<p>
+This code sample illustrates raw exchanges with a NFC target in Reader/Writer
+mode.
+</p>
+<p>Main involved classes/methods:</p>
+<ul>
+ <li>{@link com.trustedlogic.trustednfc.android.NfcManager#openTagConnection}</li>
+ <li>{@link com.trustedlogic.trustednfc.android.NfcTag}</li>
+</ul>
+
+<pre>
+public class TagReaderSample {
+
+ /** The NFC manager to access NFC features */
+ private NfcManager manager = (NfcManager) getSystemService(Context.NFC_SERVICE);
+
+ private void runTagReader() {
+ NfcTag tag = null;
+ String type;
+ byte[] cmd = { 0x01, 0x02, 0x03 };
+ byte[] res;
+
+ while (true) {
+ try {
+ Log.i("NFC example", "Please wave in front of the tag");
+ // Open a connection on next available tag
+ try {
+ tag = manager.openTagConnection();
+ } catch (NfcException e) {
+ // TODO: Handle open failure
+ }
+
+ // Look for a mifare 4k
+ type = tag.getType();
+ if (type.equals("Mifare4K")) {
+ Log.i("NFC example", "Tag detected");
+ tag.connect();
+ // Ready to communicate, we can send transceive !
+ res = tag.transceive(cmd);
+ } else {
+ Log.i("NFC example", "Unknown tag");
+ }
+ } catch (IOException e) {
+ // TODO: Handle broken connection
+ } finally {
+ if (tag != null) {
+ tag.close();
+ }
+ }
+ }
+ }
+}
+</pre>
+
+<h2>Peer-to-Peer Mode raw exchange</h2>
+
+<p>
+This code sample illustrates raw exchanges with a NFC target in Peer-to-Peer
+mode.
+</p>
+<p>Main involved classes/methods:</p>
+<ul>
+ <li>{@link com.trustedlogic.trustednfc.android.NfcManager#openP2pConnection}</li>
+ <li>{@link com.trustedlogic.trustednfc.android.P2pDevice}</li>
+ <li>{@link com.trustedlogic.trustednfc.android.P2pInitiator}</li>
+ <li>{@link com.trustedlogic.trustednfc.android.P2pTarget}</li>
+</ul>
+
+<pre>
+public class P2pSample {
+
+ /** The NFC manager to access NFC features */
+ private NfcManager manager = (NfcManager) getSystemService(Context.NFC_SERVICE);
+
+ private void runP2p() {
+ P2pDevice deviceP2p;
+ P2pInitiator initiator;
+ P2pTarget target;
+ byte[] data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+ byte[] echo = new byte[data.length * 10];
+
+ try {
+ deviceP2p = manager.openP2pConnection();
+
+ if (deviceP2p.getMode() == P2pDevice.MODE_P2P_INITIATOR) {
+ target = new P2pTarget(deviceP2p);
+ // Connect to the detected P2P target
+ target.connect();
+ // send data to the target
+ target.transceive(data);
+ // disconnect the connected target
+ target.disconnect();
+ } else if (deviceP2p.getMode() == P2pDevice.MODE_P2P_TARGET) {
+ initiator = new P2pInitiator(deviceP2p);
+ //target in receive state
+ echo = initiator.receive();
+ // send back the data received
+ initiator.send(echo);
+ }
+ } catch (IOException e0) {
+
+ } catch (NfcException e1) {
+
+ }
+ }
+}
+</pre>
+
+<h2>Peer-to-Peer Mode LLCP exchange</h2>
+
+<p>
+This code sample illustrates how to get LLCP link state notification with the declaration of a Receiver in the manifest of the application and the implementation
+of the receiver in the application.
+</p>
+<p>Manifest Example:</p>
+<pre>
+ <receiver android:name=".LlcpModeReceiverSample">
+ <intent-filter>
+ <action android:name= "com.trustedlogic.trustednfc.android.action.LLCP_LINK_STATE_CHANGED"/>
+ </intent-filter>
+ </receiver>
+</pre>
+
+<p>Receiver Example:</p>
+<ul>
+ <li>{@link com.trustedlogic.trustednfc.android.NfcManager#LLCP_LINK_STATE_CHANGED_ACTION}</li>
+ <li>{@link com.trustedlogic.trustednfc.android.NfcManager#LLCP_LINK_STATE_CHANGED_EXTRA}</li>
+</ul>
+<pre>
+public class LlcpModeReceiverSample extends BroadcastReceiver {
+ public void onReceive(Context context, Intent intent) {
+
+ if (intent.getAction().equals(NfcManager.LLCP_LINK_STATE_CHANGED_ACTION)){
+ byte[] aid = intent.getByteArrayExtra(NfcManager.LLCP_LINK_STATE_CHANGED_EXTRA);
+ /* Create an LLCP service or client and start an LLCP communication */
+ }
+ }
+</pre>
+
+
+<p>
+This code samples illustrate LLCP exchanges with a NFC Peer.
+</p>
+<p>Main involved classes/methods:</p>
+<ul>
+ <li>{@link com.trustedlogic.trustednfc.android.NfcManager#createLlcpSocket}</li>
+ <li>{@link com.trustedlogic.trustednfc.android.NfcManager#createLlcpConnectionlessSocket}</li>
+ <li>{@link com.trustedlogic.trustednfc.android.NfcManager#createLlcpServiceSocket}</li>
+ <li>{@link com.trustedlogic.trustednfc.android.LlcpSocket}</li>
+ <li>{@link com.trustedlogic.trustednfc.android.LlcpConnectionlessSocket}</li>
+ <li>{@link com.trustedlogic.trustednfc.android.LlcpPacket}</li>
+ <li>{@link com.trustedlogic.trustednfc.android.LlcpServiceSocket}</li>
+</ul>
+
+<pre>
+public class LlcpServerSample {
+
+ /** The NFC manager to access NFC features */
+ private NfcManager manager = (NfcManager) getSystemService(Context.NFC_SERVICE);
+
+ private void runLlcpClient() {
+ LlcpSocket sock;
+ byte[] data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+ byte[] echo = new byte[data.length * 10];
+ int length = 0;
+
+ sock = manager.createLlcpSocket((short) 128, (byte) 2, 1024);
+
+ // set a timeout in ms for connect request
+ sock.setConnectTimeout(10);
+
+ try {
+ // Connect to remote service
+ // NOTE: could be sock.connect("com.trusted-logic.tnfc.testapp");
+ sock.connect((byte) 0x10);
+
+ // Send data
+ for (int i = 0; i < 10; i++) {
+ sock.send(data);
+ }
+
+ // Receive echo
+ while (length < 10 * data.length) {
+ length += sock.receive(echo);
+ }
+
+ } catch (IOException e) {
+ // TODO: Handle broken connection broken (link down, remote closure
+ // or connect rejected) or Timeout expired
+ }
+ }
+}
+</pre>
+
+<pre>
+public class LlcpClientSample {
+
+ /** The NFC manager to access NFC features */
+ private NfcManager manager = (NfcManager) getSystemService(Context.NFC_SERVICE);
+
+ private void runLlcpClient() {
+ LlcpSocket sock;
+ byte[] data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+ byte[] echo = new byte[data.length * 10];
+ int length = 0;
+
+ sock = manager.createLlcpSocket((short) 128, (byte) 2, 1024);
+ try {
+ // Connect to remote service
+ // NOTE: could be sock.connect("com.trusted-logic.tnfc.testapp");
+ sock.connect((byte) 0x10);
+
+ // Send data
+ for (int i = 0; i < 10; i++) {
+ sock.send(data);
+ }
+
+ // Receive echo
+ while (length < 10 * data.length) {
+ length += sock.receive(echo);
+ }
+
+ } catch (IOException e) {
+ // TODO: Handle broken connection broken (link down, remote closure
+ // or connect rejected)
+ }
+ }
+}
+</pre>
+
+<h2>Card Emulation Mode transaction notification</h2>
+
+<p>
+This code sample illustrates how to get the card emulation notification with the declaration of a Receiver in the manifest of the application and the implementation
+of the receiver in the application.
+</p>
+<p>Manifest Example:</p>
+<pre>
+ <receiver android:name=".NfcReaderDemoReceiver">
+ <intent-filter>
+ <action android:name= "com.trustedlogic.trustednfc.android.action.TRANSACTION_DETECTED"/>
+ </intent-filter>
+ </receiver>
+</pre>
+
+<p>Receiver Example:</p>
+<ul>
+ <li>{@link com.trustedlogic.trustednfc.android.NfcManager#TRANSACTION_DETECTED_ACTION}</li>
+ <li>{@link com.trustedlogic.trustednfc.android.NfcManager#AID_EXTRA}</li>
+</ul>
+<pre>
+public class CardEmulationReceiverSample extends BroadcastReceiver {
+ public void onReceive(Context context, Intent intent) {
+
+ if (intent.getAction().equals(NfcManager.TRANSACTION_DETECTED_ACTION)){
+ byte[] aid = intent.getByteArrayExtra(NfcManager.AID_EXTRA);
+ /* Manage the AID: */
+ /* For example start an activity related to this AID value or display a popup with the AID */
+ }
+ }
+</pre>
+
+
+
+<h1>Multiple Applications rules</h1>
+
+<p>
+Several LLCP sockets can be created by a single application or by multiple
+applications by calling {@link com.trustedlogic.trustednfc.android.NfcManager#createLlcpSocket},
+{@link com.trustedlogic.trustednfc.android.NfcManager#createLlcpConnectionlessSocket} or
+{@link com.trustedlogic.trustednfc.android.NfcManager#createLlcpServiceSocket}, provided the local SAP
+numbers are differents.
+</p>
+
+<p>
+Only one application can open a raw connection by calling
+{@link com.trustedlogic.trustednfc.android.NfcManager#openTagConnection} or
+{@link com.trustedlogic.trustednfc.android.NfcManager#openP2pConnection}.
+While this application has not closed or cancelled its connection, any other
+application that attempts to open another raw connection will raise an
+exception.
+During an open connnection, the card emulation mode is always enabled and
+applications are able to receive card emulation intents.
+</p>
+
+<p>
+When an application opens a tag connection by calling
+{@link com.trustedlogic.trustednfc.android.NfcManager#openTagConnection}, this operation is exclusive, no NDEF message intent are
+broadcast while the connection is not closed or canceled.
+</p>
+
+<p>
+When an application opens a peer-to-peer connection by calling
+{@link com.trustedlogic.trustednfc.android.NfcManager#openP2pConnection}, this operation is exclusive, no LLCP intent are broadcast and LLCP sockets are
+disabled while the connection is not closed or canceled.
+</p>
+
+
+<h1>NFC Tag types</h1>
+
+<p>
+The {@link com.trustedlogic.trustednfc.android.NfcTag} type returned by
+{@link com.trustedlogic.trustednfc.android.NfcTag#getType} indicates the set of
+commands supported by the tag. These commands can be used in
+{@link com.trustedlogic.trustednfc.android.NfcTag#transceive}.
+</p>
+
+<TABLE BORDER="1">
+ <TR><TH> Tag Type </TH><TH> Returned string </TH></TR>
+ <TR><TD> Jewel/Topaz </TD><TD> Jewel </TD></TR>
+ <TR><TD> Mifare UltraLight </TD><TD> MifareUL </TD></TR>
+ <TR><TD> Mifare Standard 1K </TD><TD> Mifare1K </TD></TR>
+ <TR><TD> Mifare Standard 4K </TD><TD> Mifare4K </TD></TR>
+ <TR><TD> Mifare DESFIRE </TD><TD> MifareDESFIRE </TD></TR>
+ <TR><TD> Felica </TD><TD> Felica </TD></TR>
+ <TR><TD> ISO14443-4 A or B </TD><TD> Iso14443 </TD></TR>
+ <TR><TD> ISO15693 </TD><TD> Iso15693 </TD></TR>
+</TABLE>
+
+</body>
+</html>