/* * 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.server; import java.util.HashMap; import java.util.LinkedList; import java.util.ListIterator; import android.nfc.ErrorCodes; import android.nfc.FormatException; import android.nfc.ILlcpConnectionlessSocket; import android.nfc.ILlcpServiceSocket; import android.nfc.INfcAdapter; import android.nfc.ILlcpSocket; import android.nfc.INfcTag; import android.nfc.IP2pInitiator; import android.nfc.IP2pTarget; import android.nfc.LlcpPacket; import android.nfc.NdefMessage; import android.nfc.Tag; //import android.nfc.NfcException; //import android.nfc.NfcManager; import android.nfc.NfcAdapter; import com.trustedlogic.trustednfc.android.internal.NativeLlcpConnectionlessSocket; import com.trustedlogic.trustednfc.android.internal.NativeLlcpServiceSocket; import com.trustedlogic.trustednfc.android.internal.NativeLlcpSocket; import com.trustedlogic.trustednfc.android.internal.NativeNfcManager; import com.trustedlogic.trustednfc.android.internal.NativeNfcTag; import com.trustedlogic.trustednfc.android.internal.NativeP2pDevice; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.Process; import android.os.RemoteException; import android.provider.Settings; import android.util.Log; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; public class NfcService extends INfcAdapter.Stub implements Runnable { /** * NFC Service tag */ private static final String TAG = "NfcService"; /** * NFC features disabled state */ private static final short NFC_STATE_DISABLED = 0x00; /** * NFC features enabled state */ private static final short NFC_STATE_ENABLED = 0x01; /** * NFC Discovery for Reader mode */ private static final int DISCOVERY_MODE_READER = 0; /** * NFC Discovery for Card Emulation Mode */ private static final int DISCOVERY_MODE_CARD_EMULATION = 2; /** * LLCP Service Socket type */ private static final int LLCP_SERVICE_SOCKET_TYPE = 0; /** * LLCP Socket type */ private static final int LLCP_SOCKET_TYPE = 1; /** * LLCP Connectionless socket type */ private static final int LLCP_CONNECTIONLESS_SOCKET_TYPE = 2; /** * Maximun number of sockets managed */ private static final int LLCP_SOCKET_NB_MAX = 5; /** * Default value for the Maximum Information Unit parameter */ private static final int LLCP_LTO_DEFAULT_VALUE = 150; /** * Default value for the Maximum Information Unit parameter */ private static final int LLCP_LTO_MAX_VALUE = 255; /** * Maximun value for the Receive Window */ private static final int LLCP_RW_MAX_VALUE = 15; /** * Default value for the Maximum Information Unit parameter */ private static final int LLCP_MIU_DEFAULT_VALUE = 128; /** * Default value for the Maximum Information Unit parameter */ private static final int LLCP_MIU_MAX_VALUE = 2176; /** * Default value for the Well Known Service List parameter */ private static final int LLCP_WKS_DEFAULT_VALUE = 1; /** * Max value for the Well Known Service List parameter */ private static final int LLCP_WKS_MAX_VALUE = 15; /** * Default value for the Option parameter */ private static final int LLCP_OPT_DEFAULT_VALUE = 0; /** * Max value for the Option parameter */ private static final int LLCP_OPT_MAX_VALUE = 3; /** * LLCP Properties */ private static final int PROPERTY_LLCP_LTO = 0; private static final int PROPERTY_LLCP_MIU = 1; private static final int PROPERTY_LLCP_WKS = 2; private static final int PROPERTY_LLCP_OPT = 3; private static final String PROPERTY_LLCP_LTO_VALUE = "llcp.lto"; private static final String PROPERTY_LLCP_MIU_VALUE = "llcp.miu"; private static final String PROPERTY_LLCP_WKS_VALUE = "llcp.wks"; private static final String PROPERTY_LLCP_OPT_VALUE = "llcp.opt"; /** * NFC Reader Properties */ private static final int PROPERTY_NFC_DISCOVERY_A = 4; private static final int PROPERTY_NFC_DISCOVERY_B = 5; private static final int PROPERTY_NFC_DISCOVERY_F = 6; private static final int PROPERTY_NFC_DISCOVERY_15693 = 7; private static final int PROPERTY_NFC_DISCOVERY_NFCIP = 8; private static final String PROPERTY_NFC_DISCOVERY_A_VALUE = "discovery.iso14443A"; private static final String PROPERTY_NFC_DISCOVERY_B_VALUE = "discovery.iso14443B"; private static final String PROPERTY_NFC_DISCOVERY_F_VALUE = "discovery.felica"; private static final String PROPERTY_NFC_DISCOVERY_15693_VALUE = "discovery.iso15693"; private static final String PROPERTY_NFC_DISCOVERY_NFCIP_VALUE = "discovery.nfcip"; private final Context mContext; private final HashMap mObjectMap = new HashMap(); private final HashMap mSocketMap = new HashMap(); private final LinkedList mRegisteredSocketList = new LinkedList(); private int mLlcpLinkState = NfcAdapter.LLCP_LINK_STATE_DEACTIVATED; private int mGeneratedSocketHandle = 0; private int mNbSocketCreated = 0; private boolean mIsNfcEnabled = false; private NfcHandler mNfcHandler; private int mSelectedSeId = 0; private int mTimeout = 0; private int mNfcState; private int mNfcSecureElementState; private boolean mOpenPending = false; private final NativeNfcManager mManager; private final ILlcpSocket mLlcpSocket = new ILlcpSocket.Stub() { private final int CONNECT_FLAG = 0x01; private final int CLOSE_FLAG = 0x02; private final int RECV_FLAG = 0x04; private final int SEND_FLAG = 0x08; private int concurrencyFlags; private Object sync; private void enterCritical(int mask, int current) { int result = -1; try { while (result != 0) { synchronized(this) { result = concurrencyFlags & mask; } sync.wait(); } } catch(InterruptedException e) { } // Set flag concurrencyFlags |= current; } private void leaveCritical(int current) { synchronized(this) { // Clear flag concurrencyFlags &= ~current; } // Release waiting threads sync.notifyAll(); } public int close(int nativeHandle) throws RemoteException { NativeLlcpSocket socket = null; boolean isSuccess = false; // Check if NFC is enabled if (!mIsNfcEnabled) { return ErrorCodes.ERROR_NOT_INITIALIZED; } /* find the socket in the hmap */ socket = (NativeLlcpSocket) findSocket(nativeHandle); if (socket != null) { if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) { isSuccess = socket.doClose(); if (isSuccess) { /* Remove the socket closed from the hmap */ RemoveSocket(nativeHandle); /* Update mNbSocketCreated */ mNbSocketCreated--; return ErrorCodes.SUCCESS; } else { return ErrorCodes.ERROR_IO; } } else { /* Remove the socket closed from the hmap */ RemoveSocket(nativeHandle); /* Remove registered socket from the list */ RemoveRegisteredSocket(nativeHandle); /* Update mNbSocketCreated */ mNbSocketCreated--; return ErrorCodes.SUCCESS; } } else { return ErrorCodes.ERROR_IO; } } public int connect(int nativeHandle, int sap) throws RemoteException { NativeLlcpSocket socket = null; boolean isSuccess = false; // Check if NFC is enabled if (!mIsNfcEnabled) { return ErrorCodes.ERROR_NOT_INITIALIZED; } /* find the socket in the hmap */ socket = (NativeLlcpSocket) findSocket(nativeHandle); if (socket != null) { isSuccess = socket.doConnect(sap, socket.getConnectTimeout()); if (isSuccess) { return ErrorCodes.SUCCESS; } else { return ErrorCodes.ERROR_IO; } } else { return ErrorCodes.ERROR_IO; } } public int connectByName(int nativeHandle, String sn) throws RemoteException { NativeLlcpSocket socket = null; boolean isSuccess = false; // Check if NFC is enabled if (!mIsNfcEnabled) { return ErrorCodes.ERROR_NOT_INITIALIZED; } /* find the socket in the hmap */ socket = (NativeLlcpSocket) findSocket(nativeHandle); if (socket != null) { isSuccess = socket.doConnectBy(sn, socket.getConnectTimeout()); if (isSuccess) { return ErrorCodes.SUCCESS; } else { return ErrorCodes.ERROR_IO; } } else { return ErrorCodes.ERROR_IO; } } public int getConnectTimeout(int nativeHandle) throws RemoteException { NativeLlcpSocket socket = null; // Check if NFC is enabled if (!mIsNfcEnabled) { return ErrorCodes.ERROR_NOT_INITIALIZED; } /* find the socket in the hmap */ socket = (NativeLlcpSocket) findSocket(nativeHandle); if (socket != null) { return socket.getConnectTimeout(); } else { return 0; } } public int getLocalSap(int nativeHandle) throws RemoteException { NativeLlcpSocket socket = null; // Check if NFC is enabled if (!mIsNfcEnabled) { return ErrorCodes.ERROR_NOT_INITIALIZED; } /* find the socket in the hmap */ socket = (NativeLlcpSocket) findSocket(nativeHandle); if (socket != null) { return socket.getSap(); } else { return 0; } } public int getLocalSocketMiu(int nativeHandle) throws RemoteException { NativeLlcpSocket socket = null; // Check if NFC is enabled if (!mIsNfcEnabled) { return ErrorCodes.ERROR_NOT_INITIALIZED; } /* find the socket in the hmap */ socket = (NativeLlcpSocket) findSocket(nativeHandle); if (socket != null) { return socket.getMiu(); } else { return 0; } } public int getLocalSocketRw(int nativeHandle) throws RemoteException { NativeLlcpSocket socket = null; // Check if NFC is enabled if (!mIsNfcEnabled) { return ErrorCodes.ERROR_NOT_INITIALIZED; } /* find the socket in the hmap */ socket = (NativeLlcpSocket) findSocket(nativeHandle); if (socket != null) { return socket.getRw(); } else { return 0; } } public int getRemoteSocketMiu(int nativeHandle) throws RemoteException { NativeLlcpSocket socket = null; // Check if NFC is enabled if (!mIsNfcEnabled) { return ErrorCodes.ERROR_NOT_INITIALIZED; } /* find the socket in the hmap */ socket = (NativeLlcpSocket) findSocket(nativeHandle); if (socket != null) { if (socket.doGetRemoteSocketMiu() != 0) { return socket.doGetRemoteSocketMiu(); } else { return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED; } } else { return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED; } } public int getRemoteSocketRw(int nativeHandle) throws RemoteException { NativeLlcpSocket socket = null; // Check if NFC is enabled if (!mIsNfcEnabled) { return ErrorCodes.ERROR_NOT_INITIALIZED; } /* find the socket in the hmap */ socket = (NativeLlcpSocket) findSocket(nativeHandle); if (socket != null) { if (socket.doGetRemoteSocketRw() != 0) { return socket.doGetRemoteSocketRw(); } else { return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED; } } else { return ErrorCodes.ERROR_SOCKET_NOT_CONNECTED; } } public int receive(int nativeHandle, byte[] receiveBuffer) throws RemoteException { NativeLlcpSocket socket = null; int receiveLength = 0; // Check if NFC is enabled if (!mIsNfcEnabled) { return ErrorCodes.ERROR_NOT_INITIALIZED; } /* find the socket in the hmap */ socket = (NativeLlcpSocket) findSocket(nativeHandle); if (socket != null) { receiveLength = socket.doReceive(receiveBuffer); if (receiveLength != 0) { return receiveLength; } else { return ErrorCodes.ERROR_IO; } } else { return ErrorCodes.ERROR_IO; } } public int send(int nativeHandle, byte[] data) throws RemoteException { NativeLlcpSocket socket = null; boolean isSuccess = false; // Check if NFC is enabled if (!mIsNfcEnabled) { return ErrorCodes.ERROR_NOT_INITIALIZED; } /* find the socket in the hmap */ socket = (NativeLlcpSocket) findSocket(nativeHandle); if (socket != null) { isSuccess = socket.doSend(data); if (isSuccess) { return ErrorCodes.SUCCESS; } else { return ErrorCodes.ERROR_IO; } } else { return ErrorCodes.ERROR_IO; } } public void setConnectTimeout(int nativeHandle, int timeout) throws RemoteException { NativeLlcpSocket socket = null; /* find the socket in the hmap */ socket = (NativeLlcpSocket) findSocket(nativeHandle); if (socket != null) { socket.setConnectTimeout(timeout); } } }; private final ILlcpServiceSocket mLlcpServerSocketService = new ILlcpServiceSocket.Stub() { public int accept(int nativeHandle) throws RemoteException { NativeLlcpServiceSocket socket = null; NativeLlcpSocket clientSocket = null; // Check if NFC is enabled if (!mIsNfcEnabled) { return ErrorCodes.ERROR_NOT_INITIALIZED; } if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) { /* find the socket in the hmap */ socket = (NativeLlcpServiceSocket) findSocket(nativeHandle); if (socket != null) { clientSocket = socket.doAccept(socket.getAcceptTimeout(), socket.getMiu(), socket.getRw(), socket.getLinearBufferLength()); if (clientSocket != null) { /* Add the socket into the socket map */ mSocketMap.put(clientSocket.getHandle(), clientSocket); mNbSocketCreated++; return clientSocket.getHandle(); } else { return ErrorCodes.ERROR_IO; } } else { return ErrorCodes.ERROR_IO; } } else { return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; } } public void close(int nativeHandle) throws RemoteException { NativeLlcpServiceSocket socket = null; boolean isSuccess = false; // Check if NFC is enabled if (!mIsNfcEnabled) { return; } /* find the socket in the hmap */ socket = (NativeLlcpServiceSocket) findSocket(nativeHandle); if (socket != null) { if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) { isSuccess = socket.doClose(); if (isSuccess) { /* Remove the socket closed from the hmap */ RemoveSocket(nativeHandle); /* Update mNbSocketCreated */ mNbSocketCreated--; } } else { /* Remove the socket closed from the hmap */ RemoveSocket(nativeHandle); /* Remove registered socket from the list */ RemoveRegisteredSocket(nativeHandle); /* Update mNbSocketCreated */ mNbSocketCreated--; } } } public int getAcceptTimeout(int nativeHandle) throws RemoteException { NativeLlcpServiceSocket socket = null; // Check if NFC is enabled if (!mIsNfcEnabled) { return ErrorCodes.ERROR_NOT_INITIALIZED; } /* find the socket in the hmap */ socket = (NativeLlcpServiceSocket) findSocket(nativeHandle); if (socket != null) { return socket.getAcceptTimeout(); } else { return 0; } } public void setAcceptTimeout(int nativeHandle, int timeout) throws RemoteException { NativeLlcpServiceSocket socket = null; /* find the socket in the hmap */ socket = (NativeLlcpServiceSocket) findSocket(nativeHandle); if (socket != null) { socket.setAcceptTimeout(timeout); } } }; private final ILlcpConnectionlessSocket mLlcpConnectionlessSocketService = new ILlcpConnectionlessSocket.Stub() { public void close(int nativeHandle) throws RemoteException { NativeLlcpConnectionlessSocket socket = null; boolean isSuccess = false; // Check if NFC is enabled if (!mIsNfcEnabled) { return; } /* find the socket in the hmap */ socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle); if (socket != null) { if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) { isSuccess = socket.doClose(); if (isSuccess) { /* Remove the socket closed from the hmap */ RemoveSocket(nativeHandle); /* Update mNbSocketCreated */ mNbSocketCreated--; } } else { /* Remove the socket closed from the hmap */ RemoveSocket(nativeHandle); /* Remove registered socket from the list */ RemoveRegisteredSocket(nativeHandle); /* Update mNbSocketCreated */ mNbSocketCreated--; } } } public int getSap(int nativeHandle) throws RemoteException { NativeLlcpConnectionlessSocket socket = null; // Check if NFC is enabled if (!mIsNfcEnabled) { return ErrorCodes.ERROR_NOT_INITIALIZED; } /* find the socket in the hmap */ socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle); if (socket != null) { return socket.getSap(); } else { return 0; } } public LlcpPacket receiveFrom(int nativeHandle) throws RemoteException { NativeLlcpConnectionlessSocket socket = null; LlcpPacket packet; // Check if NFC is enabled if (!mIsNfcEnabled) { return null; } /* find the socket in the hmap */ socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle); if (socket != null) { packet = socket.doReceiveFrom(socket.getLinkMiu()); if (packet != null) { return packet; } return null; } else { return null; } } public int sendTo(int nativeHandle, LlcpPacket packet) throws RemoteException { NativeLlcpConnectionlessSocket socket = null; boolean isSuccess = false; // Check if NFC is enabled if (!mIsNfcEnabled) { return ErrorCodes.ERROR_NOT_INITIALIZED; } /* find the socket in the hmap */ socket = (NativeLlcpConnectionlessSocket) findSocket(nativeHandle); if (socket != null) { isSuccess = socket.doSendTo(packet.getRemoteSap(), packet.getDataBuffer()); if (isSuccess) { return ErrorCodes.SUCCESS; } else { return ErrorCodes.ERROR_IO; } } else { return ErrorCodes.ERROR_IO; } } }; private final INfcTag mNfcTagService = new INfcTag.Stub() { public int close(int nativeHandle) throws RemoteException { NativeNfcTag tag = null; // Check if NFC is enabled if (!mIsNfcEnabled) { return ErrorCodes.ERROR_NOT_INITIALIZED; } /* find the tag in the hmap */ tag = (NativeNfcTag) findObject(nativeHandle); if (tag != null) { if (tag.doDisconnect()) { /* Remove the device from the hmap */ RemoveObject(nativeHandle); /* Restart polling loop for notification */ mManager.enableDiscovery(DISCOVERY_MODE_READER); mOpenPending = false; return ErrorCodes.SUCCESS; } } /* Restart polling loop for notification */ mManager.enableDiscovery(DISCOVERY_MODE_READER); mOpenPending = false; return ErrorCodes.ERROR_DISCONNECT; } public int connect(int nativeHandle) throws RemoteException { NativeNfcTag tag = null; // Check if NFC is enabled if (!mIsNfcEnabled) { return ErrorCodes.ERROR_NOT_INITIALIZED; } /* find the tag in the hmap */ tag = (NativeNfcTag) findObject(nativeHandle); if (tag != null) { if (tag.doConnect()) return ErrorCodes.SUCCESS; } /* Restart polling loop for notification */ mManager.enableDiscovery(DISCOVERY_MODE_READER); mOpenPending = false; return ErrorCodes.ERROR_CONNECT; } public String getType(int nativeHandle) throws RemoteException { NativeNfcTag tag = null; String type; // Check if NFC is enabled if (!mIsNfcEnabled) { return null; } /* find the tag in the hmap */ tag = (NativeNfcTag) findObject(nativeHandle); if (tag != null) { type = tag.getType(); return type; } return null; } public byte[] getUid(int nativeHandle) throws RemoteException { NativeNfcTag tag = null; byte[] uid; // Check if NFC is enabled if (!mIsNfcEnabled) { return null; } /* find the tag in the hmap */ tag = (NativeNfcTag) findObject(nativeHandle); if (tag != null) { uid = tag.getUid(); return uid; } return null; } public boolean isNdef(int nativeHandle) throws RemoteException { NativeNfcTag tag = null; boolean isSuccess = false; // Check if NFC is enabled if (!mIsNfcEnabled) { return isSuccess; } /* find the tag in the hmap */ tag = (NativeNfcTag) findObject(nativeHandle); if (tag != null) { isSuccess = tag.checkNDEF(); } return isSuccess; } public byte[] transceive(int nativeHandle, byte[] data) throws RemoteException { NativeNfcTag tag = null; byte[] response; // Check if NFC is enabled if (!mIsNfcEnabled) { return null; } /* find the tag in the hmap */ tag = (NativeNfcTag) findObject(nativeHandle); if (tag != null) { response = tag.doTransceive(data); return response; } return null; } public NdefMessage read(int nativeHandle) throws RemoteException { NativeNfcTag tag; // Check if NFC is enabled if (!mIsNfcEnabled) { return null; } /* find the tag in the hmap */ tag = (NativeNfcTag) findObject(nativeHandle); if (tag != null) { byte[] buf = tag.doRead(); if (buf == null) return null; /* Create an NdefMessage */ try { return new NdefMessage(buf); } catch (FormatException e) { return null; } } return null; } public int write(int nativeHandle, NdefMessage msg) throws RemoteException { NativeNfcTag tag; // Check if NFC is enabled if (!mIsNfcEnabled) { return ErrorCodes.ERROR_NOT_INITIALIZED; } /* find the tag in the hmap */ tag = (NativeNfcTag) findObject(nativeHandle); if (tag == null) { return ErrorCodes.ERROR_IO; } if (tag.doWrite(msg.toByteArray())) { return ErrorCodes.SUCCESS; } else { return ErrorCodes.ERROR_IO; } } public int getLastError(int nativeHandle) throws RemoteException { // TODO Auto-generated method stub return 0; } public int getModeHint(int nativeHandle) throws RemoteException { // TODO Auto-generated method stub return 0; } public int makeReadOnly(int nativeHandle) throws RemoteException { // TODO Auto-generated method stub return 0; } }; private final IP2pInitiator mP2pInitiatorService = new IP2pInitiator.Stub() { public byte[] getGeneralBytes(int nativeHandle) throws RemoteException { NativeP2pDevice device; // Check if NFC is enabled if (!mIsNfcEnabled) { return null; } /* find the device in the hmap */ device = (NativeP2pDevice) findObject(nativeHandle); if (device != null) { byte[] buff = device.getGeneralBytes(); if (buff == null) return null; return buff; } return null; } public int getMode(int nativeHandle) throws RemoteException { NativeP2pDevice device; // Check if NFC is enabled if (!mIsNfcEnabled) { return ErrorCodes.ERROR_NOT_INITIALIZED; } /* find the device in the hmap */ device = (NativeP2pDevice) findObject(nativeHandle); if (device != null) { return device.getMode(); } return ErrorCodes.ERROR_INVALID_PARAM; } public byte[] receive(int nativeHandle) throws RemoteException { NativeP2pDevice device; // Check if NFC is enabled if (!mIsNfcEnabled) { return null; } /* find the device in the hmap */ device = (NativeP2pDevice) findObject(nativeHandle); if (device != null) { byte[] buff = device.doReceive(); if (buff == null) return null; return buff; } /* Restart polling loop for notification */ mManager.enableDiscovery(DISCOVERY_MODE_READER); mOpenPending = false; return null; } public boolean send(int nativeHandle, byte[] data) throws RemoteException { NativeP2pDevice device; boolean isSuccess = false; // Check if NFC is enabled if (!mIsNfcEnabled) { return isSuccess; } /* find the device in the hmap */ device = (NativeP2pDevice) findObject(nativeHandle); if (device != null) { isSuccess = device.doSend(data); } return isSuccess; } }; private final IP2pTarget mP2pTargetService = new IP2pTarget.Stub() { public int connect(int nativeHandle) throws RemoteException { NativeP2pDevice device; // Check if NFC is enabled if (!mIsNfcEnabled) { return ErrorCodes.ERROR_NOT_INITIALIZED; } /* find the device in the hmap */ device = (NativeP2pDevice) findObject(nativeHandle); if (device != null) { if (device.doConnect()) { return ErrorCodes.SUCCESS; } } return ErrorCodes.ERROR_CONNECT; } public boolean disconnect(int nativeHandle) throws RemoteException { NativeP2pDevice device; boolean isSuccess = false; // Check if NFC is enabled if (!mIsNfcEnabled) { return isSuccess; } /* find the device in the hmap */ device = (NativeP2pDevice) findObject(nativeHandle); if (device != null) { if (isSuccess = device.doDisconnect()) { mOpenPending = false; /* remove the device from the hmap */ RemoveObject(nativeHandle); /* Restart polling loop for notification */ mManager.enableDiscovery(DISCOVERY_MODE_READER); } } return isSuccess; } public byte[] getGeneralBytes(int nativeHandle) throws RemoteException { NativeP2pDevice device; // Check if NFC is enabled if (!mIsNfcEnabled) { return null; } /* find the device in the hmap */ device = (NativeP2pDevice) findObject(nativeHandle); if (device != null) { byte[] buff = device.getGeneralBytes(); if (buff == null) return null; return buff; } return null; } public int getMode(int nativeHandle) throws RemoteException { NativeP2pDevice device; // Check if NFC is enabled if (!mIsNfcEnabled) { return ErrorCodes.ERROR_NOT_INITIALIZED; } /* find the device in the hmap */ device = (NativeP2pDevice) findObject(nativeHandle); if (device != null) { return device.getMode(); } return ErrorCodes.ERROR_INVALID_PARAM; } public byte[] transceive(int nativeHandle, byte[] data) throws RemoteException { NativeP2pDevice device; // Check if NFC is enabled if (!mIsNfcEnabled) { return null; } /* find the device in the hmap */ device = (NativeP2pDevice) findObject(nativeHandle); if (device != null) { byte[] buff = device.doTransceive(data); if (buff == null) return null; return buff; } return null; } }; private class NfcHandler extends Handler { @Override public void handleMessage(Message msg) { try { } catch (Exception e) { // Log, don't crash! Log.e(TAG, "Exception in NfcHandler.handleMessage:", e); } } }; public NfcService(Context context) { super(); mContext = context; mManager = new NativeNfcManager(mContext); mContext.registerReceiver(mNfcServiceReceiver, new IntentFilter( NativeNfcManager.INTERNAL_LLCP_LINK_STATE_CHANGED_ACTION)); mContext.registerReceiver(mNfcServiceReceiver, new IntentFilter( NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED)); mContext.registerReceiver(mNfcServiceReceiver, new IntentFilter( NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION)); Thread thread = new Thread(null, this, "NfcService"); thread.start(); mManager.initializeNativeStructure(); int nfcState = Settings.System.getInt(mContext.getContentResolver(), Settings.System.NFC_ON, 0); if (nfcState == NFC_STATE_ENABLED) { if (this._enable()) { } } } public void run() { Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); Looper.prepare(); mNfcHandler = new NfcHandler(); Looper.loop(); } public void cancel() throws RemoteException { mContext.enforceCallingPermission(android.Manifest.permission.NFC_RAW, "NFC_RAW permission required to cancel NFC opening"); if (mOpenPending) { mOpenPending = false; mManager.doCancel(); /* Restart polling loop for notification */ mManager.enableDiscovery(DISCOVERY_MODE_READER); } } public int createLlcpConnectionlessSocket(int sap) throws RemoteException { // Check if NFC is enabled if (!mIsNfcEnabled) { return ErrorCodes.ERROR_NOT_INITIALIZED; } mContext.enforceCallingPermission(android.Manifest.permission.NFC_LLCP, "NFC_LLCP permission required for LLCP operations with NFC service"); /* Check SAP is not already used */ /* Check nb socket created */ if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) { /* Store the socket handle */ int sockeHandle = mGeneratedSocketHandle; if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) { NativeLlcpConnectionlessSocket socket; socket = mManager.doCreateLlcpConnectionlessSocket(sap); if (socket != null) { /* Update the number of socket created */ mNbSocketCreated++; /* Add the socket into the socket map */ mSocketMap.put(sockeHandle, socket); return sockeHandle; } else { /* * socket creation error - update the socket handle * generation */ mGeneratedSocketHandle -= 1; /* Get Error Status */ int errorStatus = mManager.doGetLastError(); switch (errorStatus) { case ErrorCodes.ERROR_BUFFER_TO_SMALL: return ErrorCodes.ERROR_BUFFER_TO_SMALL; case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES: return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; default: return ErrorCodes.ERROR_SOCKET_CREATION; } } } else { /* Check SAP is not already used */ if (!CheckSocketSap(sap)) { return ErrorCodes.ERROR_SAP_USED; } NativeLlcpConnectionlessSocket socket = new NativeLlcpConnectionlessSocket(sap); /* Add the socket into the socket map */ mSocketMap.put(sockeHandle, socket); /* Update the number of socket created */ mNbSocketCreated++; /* Create new registered socket */ RegisteredSocket registeredSocket = new RegisteredSocket( LLCP_CONNECTIONLESS_SOCKET_TYPE, sockeHandle, sap); /* Put this socket into a list of registered socket */ mRegisteredSocketList.add(registeredSocket); } /* update socket handle generation */ mGeneratedSocketHandle++; return sockeHandle; } else { /* No socket available */ return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; } } public int createLlcpServiceSocket(int sap, String sn, int miu, int rw, int linearBufferLength) throws RemoteException { // Check if NFC is enabled if (!mIsNfcEnabled) { return ErrorCodes.ERROR_NOT_INITIALIZED; } mContext.enforceCallingPermission(android.Manifest.permission.NFC_LLCP, "NFC_LLCP permission required for LLCP operations with NFC service"); if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) { int sockeHandle = mGeneratedSocketHandle; if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) { NativeLlcpServiceSocket socket; socket = mManager.doCreateLlcpServiceSocket(sap, sn, miu, rw, linearBufferLength); if (socket != null) { /* Update the number of socket created */ mNbSocketCreated++; /* Add the socket into the socket map */ mSocketMap.put(sockeHandle, socket); } else { /* socket creation error - update the socket handle counter */ mGeneratedSocketHandle -= 1; /* Get Error Status */ int errorStatus = mManager.doGetLastError(); switch (errorStatus) { case ErrorCodes.ERROR_BUFFER_TO_SMALL: return ErrorCodes.ERROR_BUFFER_TO_SMALL; case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES: return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; default: return ErrorCodes.ERROR_SOCKET_CREATION; } } } else { /* Check SAP is not already used */ if (!CheckSocketSap(sap)) { return ErrorCodes.ERROR_SAP_USED; } /* Service Name */ if (!CheckSocketServiceName(sn)) { return ErrorCodes.ERROR_SERVICE_NAME_USED; } /* Check socket options */ if (!CheckSocketOptions(miu, rw, linearBufferLength)) { return ErrorCodes.ERROR_SOCKET_OPTIONS; } NativeLlcpServiceSocket socket = new NativeLlcpServiceSocket(sn); /* Add the socket into the socket map */ mSocketMap.put(sockeHandle, socket); /* Update the number of socket created */ mNbSocketCreated++; /* Create new registered socket */ RegisteredSocket registeredSocket = new RegisteredSocket(LLCP_SERVICE_SOCKET_TYPE, sockeHandle, sap, sn, miu, rw, linearBufferLength); /* Put this socket into a list of registered socket */ mRegisteredSocketList.add(registeredSocket); } /* update socket handle generation */ mGeneratedSocketHandle += 1; Log.d(TAG, "Llcp Service Socket Handle =" + sockeHandle); return sockeHandle; } else { /* No socket available */ return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; } } public int createLlcpSocket(int sap, int miu, int rw, int linearBufferLength) throws RemoteException { // Check if NFC is enabled if (!mIsNfcEnabled) { return ErrorCodes.ERROR_NOT_INITIALIZED; } mContext.enforceCallingPermission(android.Manifest.permission.NFC_LLCP, "NFC_LLCP permission required for LLCP operations with NFC service"); if (mNbSocketCreated < LLCP_SOCKET_NB_MAX) { int sockeHandle = mGeneratedSocketHandle; if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) { NativeLlcpSocket socket; socket = mManager.doCreateLlcpSocket(sap, miu, rw, linearBufferLength); if (socket != null) { /* Update the number of socket created */ mNbSocketCreated++; /* Add the socket into the socket map */ mSocketMap.put(sockeHandle, socket); } else { /* * socket creation error - update the socket handle * generation */ mGeneratedSocketHandle -= 1; /* Get Error Status */ int errorStatus = mManager.doGetLastError(); switch (errorStatus) { case ErrorCodes.ERROR_BUFFER_TO_SMALL: return ErrorCodes.ERROR_BUFFER_TO_SMALL; case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES: return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; default: return ErrorCodes.ERROR_SOCKET_CREATION; } } } else { /* Check SAP is not already used */ if (!CheckSocketSap(sap)) { return ErrorCodes.ERROR_SAP_USED; } /* Check Socket options */ if (!CheckSocketOptions(miu, rw, linearBufferLength)) { return ErrorCodes.ERROR_SOCKET_OPTIONS; } NativeLlcpSocket socket = new NativeLlcpSocket(sap, miu, rw); /* Add the socket into the socket map */ mSocketMap.put(sockeHandle, socket); /* Update the number of socket created */ mNbSocketCreated++; /* Create new registered socket */ RegisteredSocket registeredSocket = new RegisteredSocket(LLCP_SOCKET_TYPE, sockeHandle, sap, miu, rw, linearBufferLength); /* Put this socket into a list of registered socket */ mRegisteredSocketList.add(registeredSocket); } /* update socket handle generation */ mGeneratedSocketHandle++; return sockeHandle; } else { /* No socket available */ return ErrorCodes.ERROR_INSUFFICIENT_RESOURCES; } } public int deselectSecureElement() throws RemoteException { // Check if NFC is enabled if (!mIsNfcEnabled) { return ErrorCodes.ERROR_NOT_INITIALIZED; } if (mSelectedSeId == 0) { return ErrorCodes.ERROR_NO_SE_CONNECTED; } mContext.enforceCallingPermission(android.Manifest.permission.NFC_ADMIN, "NFC_ADMIN permission required to deselect NFC Secure Element"); mManager.doDeselectSecureElement(mSelectedSeId); mNfcSecureElementState = 0; mSelectedSeId = 0; /* Store that a secure element is deselected */ Settings.System.putInt(mContext.getContentResolver(), Settings.System.NFC_SECURE_ELEMENT_ON, 0); /* Reset Secure Element ID */ Settings.System.putInt(mContext.getContentResolver(), Settings.System.NFC_SECURE_ELEMENT_ID, 0); return ErrorCodes.SUCCESS; } public boolean disable() throws RemoteException { boolean isSuccess = false; mContext.enforceCallingPermission(android.Manifest.permission.NFC_ADMIN, "NFC_ADMIN permission required to disable NFC service"); if (isEnabled()) { isSuccess = mManager.deinitialize(); if (isSuccess) { mIsNfcEnabled = false; } } updateNfcOnSetting(); return isSuccess; } public boolean enable() throws RemoteException { boolean isSuccess = false; mContext.enforceCallingPermission(android.Manifest.permission.NFC_ADMIN, "NFC_ADMIN permission required to enable NFC service"); if (!isEnabled()) { reset(); isSuccess = _enable(); } return isSuccess; } private boolean _enable() { boolean isSuccess = mManager.initialize(); if (isSuccess) { /* Check persistent properties */ checkProperties(); /* Check Secure Element setting */ mNfcSecureElementState = Settings.System.getInt(mContext.getContentResolver(), Settings.System.NFC_SECURE_ELEMENT_ON, 0); if (mNfcSecureElementState == 1) { int secureElementId = Settings.System.getInt(mContext.getContentResolver(), Settings.System.NFC_SECURE_ELEMENT_ID, 0); int[] Se_list = mManager.doGetSecureElementList(); if (Se_list != null) { for (int i = 0; i < Se_list.length; i++) { if (Se_list[i] == secureElementId) { mManager.doSelectSecureElement(Se_list[i]); mSelectedSeId = Se_list[i]; break; } } } } /* Start polling loop */ mManager.enableDiscovery(DISCOVERY_MODE_READER); mIsNfcEnabled = true; } else { mIsNfcEnabled = false; } updateNfcOnSetting(); return isSuccess; } private void updateNfcOnSetting() { int state; if (mIsNfcEnabled) { state = NFC_STATE_ENABLED; } else { state = NFC_STATE_DISABLED; } Settings.System.putInt(mContext.getContentResolver(), Settings.System.NFC_ON, state); } private void checkProperties() { int value; /* LLCP LTO */ value = Settings.System.getInt(mContext.getContentResolver(), Settings.System.NFC_LLCP_LTO, LLCP_LTO_DEFAULT_VALUE); Settings.System.putInt(mContext.getContentResolver(), Settings.System.NFC_LLCP_LTO, value); mManager.doSetProperties(PROPERTY_LLCP_LTO, value); /* LLCP MIU */ value = Settings.System.getInt(mContext.getContentResolver(), Settings.System.NFC_LLCP_MIU, LLCP_MIU_DEFAULT_VALUE); Settings.System.putInt(mContext.getContentResolver(), Settings.System.NFC_LLCP_MIU, value); mManager.doSetProperties(PROPERTY_LLCP_MIU, value); /* LLCP WKS */ value = Settings.System.getInt(mContext.getContentResolver(), Settings.System.NFC_LLCP_WKS, LLCP_WKS_DEFAULT_VALUE); Settings.System.putInt(mContext.getContentResolver(), Settings.System.NFC_LLCP_WKS, value); mManager.doSetProperties(PROPERTY_LLCP_WKS, value); /* LLCP OPT */ value = Settings.System.getInt(mContext.getContentResolver(), Settings.System.NFC_LLCP_OPT, LLCP_OPT_DEFAULT_VALUE); Settings.System.putInt(mContext.getContentResolver(), Settings.System.NFC_LLCP_OPT, value); mManager.doSetProperties(PROPERTY_LLCP_OPT, value); /* NFC READER A */ value = Settings.System.getInt(mContext.getContentResolver(), Settings.System.NFC_DISCOVERY_A, 1); Settings.System.putInt(mContext.getContentResolver(), Settings.System.NFC_DISCOVERY_A, value); mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_A, value); /* NFC READER B */ value = Settings.System.getInt(mContext.getContentResolver(), Settings.System.NFC_DISCOVERY_B, 1); Settings.System.putInt(mContext.getContentResolver(), Settings.System.NFC_DISCOVERY_B, value); mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_B, value); /* NFC READER F */ value = Settings.System.getInt(mContext.getContentResolver(), Settings.System.NFC_DISCOVERY_F, 1); Settings.System.putInt(mContext.getContentResolver(), Settings.System.NFC_DISCOVERY_F, value); mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_F, value); /* NFC READER 15693 */ value = Settings.System.getInt(mContext.getContentResolver(), Settings.System.NFC_DISCOVERY_15693, 1); Settings.System.putInt(mContext.getContentResolver(), Settings.System.NFC_DISCOVERY_15693, value); mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_15693, value); /* NFC NFCIP */ value = Settings.System.getInt(mContext.getContentResolver(), Settings.System.NFC_DISCOVERY_NFCIP, 1); Settings.System.putInt(mContext.getContentResolver(), Settings.System.NFC_DISCOVERY_NFCIP, value); mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_NFCIP, value); } public ILlcpConnectionlessSocket getLlcpConnectionlessInterface() throws RemoteException { return mLlcpConnectionlessSocketService; } public ILlcpSocket getLlcpInterface() throws RemoteException { return mLlcpSocket; } public ILlcpServiceSocket getLlcpServiceInterface() throws RemoteException { return mLlcpServerSocketService; } public INfcTag getNfcTagInterface() throws RemoteException { return mNfcTagService; } public int getOpenTimeout() throws RemoteException { return mTimeout; } public IP2pInitiator getP2pInitiatorInterface() throws RemoteException { return mP2pInitiatorService; } public IP2pTarget getP2pTargetInterface() throws RemoteException { return mP2pTargetService; } public String getProperties(String param) throws RemoteException { int value; if (param == null) { return "Wrong parameter"; } if (param.equals(PROPERTY_LLCP_LTO_VALUE)) { value = Settings.System.getInt(mContext.getContentResolver(), Settings.System.NFC_LLCP_LTO, 0); } else if (param.equals(PROPERTY_LLCP_MIU_VALUE)) { value = Settings.System.getInt(mContext.getContentResolver(), Settings.System.NFC_LLCP_MIU, 0); } else if (param.equals(PROPERTY_LLCP_WKS_VALUE)) { value = Settings.System.getInt(mContext.getContentResolver(), Settings.System.NFC_LLCP_WKS, 0); } else if (param.equals(PROPERTY_LLCP_OPT_VALUE)) { value = Settings.System.getInt(mContext.getContentResolver(), Settings.System.NFC_LLCP_OPT, 0); } else if (param.equals(PROPERTY_NFC_DISCOVERY_A_VALUE)) { value = Settings.System.getInt(mContext.getContentResolver(), Settings.System.NFC_DISCOVERY_A, 0); } else if (param.equals(PROPERTY_NFC_DISCOVERY_B_VALUE)) { value = Settings.System.getInt(mContext.getContentResolver(), Settings.System.NFC_DISCOVERY_B, 0); } else if (param.equals(PROPERTY_NFC_DISCOVERY_F_VALUE)) { value = Settings.System.getInt(mContext.getContentResolver(), Settings.System.NFC_DISCOVERY_F, 0); } else if (param.equals(PROPERTY_NFC_DISCOVERY_NFCIP_VALUE)) { value = Settings.System.getInt(mContext.getContentResolver(), Settings.System.NFC_DISCOVERY_NFCIP, 0); } else if (param.equals(PROPERTY_NFC_DISCOVERY_15693_VALUE)) { value = Settings.System.getInt(mContext.getContentResolver(), Settings.System.NFC_DISCOVERY_15693, 0); } else { return "Unknown property"; } if (param.equals(PROPERTY_NFC_DISCOVERY_A_VALUE) || param.equals(PROPERTY_NFC_DISCOVERY_B_VALUE) || param.equals(PROPERTY_NFC_DISCOVERY_F_VALUE) || param.equals(PROPERTY_NFC_DISCOVERY_NFCIP_VALUE) || param.equals(PROPERTY_NFC_DISCOVERY_15693_VALUE)) { if (value == 0) { return "false"; } else if (value == 1) { return "true"; } else { return "Unknown Value"; } }else{ return "" + value; } } public int[] getSecureElementList() throws RemoteException { int[] list = null; if (mIsNfcEnabled == true) { list = mManager.doGetSecureElementList(); } return list; } public int getSelectedSecureElement() throws RemoteException { return mSelectedSeId; } public boolean isEnabled() throws RemoteException { return mIsNfcEnabled; } public int openP2pConnection() throws RemoteException { // Check if NFC is enabled if (!mIsNfcEnabled) { return ErrorCodes.ERROR_NOT_INITIALIZED; } mContext.enforceCallingPermission(android.Manifest.permission.NFC_RAW, "NFC_RAW permission required to open NFC P2P connection"); if (!mOpenPending) { NativeP2pDevice device; mOpenPending = true; device = mManager.doOpenP2pConnection(mTimeout); if (device != null) { /* add device to the Hmap */ mObjectMap.put(device.getHandle(), device); return device.getHandle(); } else { mOpenPending = false; /* Restart polling loop for notification */ mManager.enableDiscovery(DISCOVERY_MODE_READER); return ErrorCodes.ERROR_IO; } } else { return ErrorCodes.ERROR_BUSY; } } public void openTagConnection(Tag tag) throws RemoteException { NativeNfcTag nativeTag = new NativeNfcTag(tag.getHandle(), "", tag.getId()); mObjectMap.put(nativeTag.getHandle(), nativeTag); } public int selectSecureElement(int seId) throws RemoteException { // Check if NFC is enabled if (!mIsNfcEnabled) { return ErrorCodes.ERROR_NOT_INITIALIZED; } if (mSelectedSeId == seId) { return ErrorCodes.ERROR_SE_ALREADY_SELECTED; } if (mSelectedSeId != 0) { return ErrorCodes.ERROR_SE_CONNECTED; } mContext.enforceCallingPermission(android.Manifest.permission.NFC_ADMIN, "NFC_ADMIN permission required to select NFC Secure Element"); mSelectedSeId = seId; mManager.doSelectSecureElement(mSelectedSeId); /* Store that a secure element is selected */ Settings.System.putInt(mContext.getContentResolver(), Settings.System.NFC_SECURE_ELEMENT_ON, 1); /* Store the ID of the Secure Element Selected */ Settings.System.putInt(mContext.getContentResolver(), Settings.System.NFC_SECURE_ELEMENT_ID, mSelectedSeId); mNfcSecureElementState = 1; return ErrorCodes.SUCCESS; } public void setOpenTimeout(int timeout) throws RemoteException { mContext.enforceCallingPermission(android.Manifest.permission.NFC_RAW, "NFC_RAW permission required to set NFC connection timeout"); mTimeout = timeout; } public int setProperties(String param, String value) throws RemoteException { mContext.enforceCallingPermission(android.Manifest.permission.NFC_ADMIN, "NFC_ADMIN permission required to set NFC Properties"); if (isEnabled()) { return ErrorCodes.ERROR_NFC_ON; } int val; /* Check params validity */ if (param == null || value == null) { return ErrorCodes.ERROR_INVALID_PARAM; } if (param.equals(PROPERTY_LLCP_LTO_VALUE)) { val = Integer.parseInt(value); /* Check params */ if (val > LLCP_LTO_MAX_VALUE) return ErrorCodes.ERROR_INVALID_PARAM; /* Store value */ Settings.System .putInt(mContext.getContentResolver(), Settings.System.NFC_LLCP_LTO, val); /* Update JNI */ mManager.doSetProperties(PROPERTY_LLCP_LTO, val); } else if (param.equals(PROPERTY_LLCP_MIU_VALUE)) { val = Integer.parseInt(value); /* Check params */ if ((val < LLCP_MIU_DEFAULT_VALUE) || (val > LLCP_MIU_MAX_VALUE)) return ErrorCodes.ERROR_INVALID_PARAM; /* Store value */ Settings.System .putInt(mContext.getContentResolver(), Settings.System.NFC_LLCP_MIU, val); /* Update JNI */ mManager.doSetProperties(PROPERTY_LLCP_MIU, val); } else if (param.equals(PROPERTY_LLCP_WKS_VALUE)) { val = Integer.parseInt(value); /* Check params */ if (val > LLCP_WKS_MAX_VALUE) return ErrorCodes.ERROR_INVALID_PARAM; /* Store value */ Settings.System .putInt(mContext.getContentResolver(), Settings.System.NFC_LLCP_WKS, val); /* Update JNI */ mManager.doSetProperties(PROPERTY_LLCP_WKS, val); } else if (param.equals(PROPERTY_LLCP_OPT_VALUE)) { val = Integer.parseInt(value); /* Check params */ if (val > LLCP_OPT_MAX_VALUE) return ErrorCodes.ERROR_INVALID_PARAM; /* Store value */ Settings.System .putInt(mContext.getContentResolver(), Settings.System.NFC_LLCP_OPT, val); /* Update JNI */ mManager.doSetProperties(PROPERTY_LLCP_OPT, val); } else if (param.equals(PROPERTY_NFC_DISCOVERY_A_VALUE)) { /* Check params */ if (value.equals("true")) { val = 1; } else if (value.equals("false")) { val = 0; } else { return ErrorCodes.ERROR_INVALID_PARAM; } /* Store value */ Settings.System.putInt(mContext.getContentResolver(), Settings.System.NFC_DISCOVERY_A, val); /* Update JNI */ mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_A, val); } else if (param.equals(PROPERTY_NFC_DISCOVERY_B_VALUE)) { /* Check params */ if (value.equals("true")) { val = 1; } else if (value.equals("false")) { val = 0; } else { return ErrorCodes.ERROR_INVALID_PARAM; } /* Store value */ Settings.System.putInt(mContext.getContentResolver(), Settings.System.NFC_DISCOVERY_B, val); /* Update JNI */ mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_B, val); } else if (param.equals(PROPERTY_NFC_DISCOVERY_F_VALUE)) { /* Check params */ if (value.equals("true")) { val = 1; } else if (value.equals("false")) { val = 0; } else { return ErrorCodes.ERROR_INVALID_PARAM; } /* Store value */ Settings.System.putInt(mContext.getContentResolver(), Settings.System.NFC_DISCOVERY_F, val); /* Update JNI */ mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_F, val); } else if (param.equals(PROPERTY_NFC_DISCOVERY_15693_VALUE)) { /* Check params */ if (value.equals("true")) { val = 1; } else if (value.equals("false")) { val = 0; } else { return ErrorCodes.ERROR_INVALID_PARAM; } /* Store value */ Settings.System.putInt(mContext.getContentResolver(), Settings.System.NFC_DISCOVERY_15693, val); /* Update JNI */ mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_15693, val); } else if (param.equals(PROPERTY_NFC_DISCOVERY_NFCIP_VALUE)) { /* Check params */ if (value.equals("true")) { val = 1; } else if (value.equals("false")) { val = 0; } else { return ErrorCodes.ERROR_INVALID_PARAM; } /* Store value */ Settings.System.putInt(mContext.getContentResolver(), Settings.System.NFC_DISCOVERY_NFCIP, val); /* Update JNI */ mManager.doSetProperties(PROPERTY_NFC_DISCOVERY_NFCIP, val); } else { return ErrorCodes.ERROR_INVALID_PARAM; } return ErrorCodes.SUCCESS; } public NdefMessage localGet() throws RemoteException { // TODO Auto-generated method stub return null; } public void localSet(NdefMessage message) throws RemoteException { // TODO Auto-generated method stub } // Reset all internals private void reset() { // Clear tables mObjectMap.clear(); mSocketMap.clear(); mRegisteredSocketList.clear(); // Reset variables mLlcpLinkState = NfcAdapter.LLCP_LINK_STATE_DEACTIVATED; mNbSocketCreated = 0; mIsNfcEnabled = false; mSelectedSeId = 0; mTimeout = 0; mNfcState = NFC_STATE_DISABLED; mOpenPending = false; } private Object findObject(int key) { Object device = null; device = mObjectMap.get(key); if (device == null) { Log.w(TAG, "Handle not found !"); } return device; } private void RemoveObject(int key) { mObjectMap.remove(key); } private Object findSocket(int key) { Object socket = null; socket = mSocketMap.get(key); return socket; } private void RemoveSocket(int key) { mSocketMap.remove(key); } private boolean CheckSocketSap(int sap) { /* List of sockets registered */ ListIterator it = mRegisteredSocketList.listIterator(); while (it.hasNext()) { RegisteredSocket registeredSocket = it.next(); if (sap == registeredSocket.mSap) { /* SAP already used */ return false; } } return true; } private boolean CheckSocketOptions(int miu, int rw, int linearBufferlength) { if (rw > LLCP_RW_MAX_VALUE || miu < LLCP_MIU_DEFAULT_VALUE || linearBufferlength < miu) { return false; } return true; } private boolean CheckSocketServiceName(String sn) { /* List of sockets registered */ ListIterator it = mRegisteredSocketList.listIterator(); while (it.hasNext()) { RegisteredSocket registeredSocket = it.next(); if (sn.equals(registeredSocket.mServiceName)) { /* Service Name already used */ return false; } } return true; } private void RemoveRegisteredSocket(int nativeHandle) { /* check if sockets are registered */ ListIterator it = mRegisteredSocketList.listIterator(); while (it.hasNext()) { RegisteredSocket registeredSocket = it.next(); if (registeredSocket.mHandle == nativeHandle) { /* remove the registered socket from the list */ it.remove(); Log.d(TAG, "socket removed"); } } } /* * RegisteredSocket class to store the creation request of socket until the * LLCP link in not activated */ private class RegisteredSocket { private final int mType; private final int mHandle; private final int mSap; private int mMiu; private int mRw; private String mServiceName; private int mlinearBufferLength; RegisteredSocket(int type, int handle, int sap, String sn, int miu, int rw, int linearBufferLength) { mType = type; mHandle = handle; mSap = sap; mServiceName = sn; mRw = rw; mMiu = miu; mlinearBufferLength = linearBufferLength; } RegisteredSocket(int type, int handle, int sap, int miu, int rw, int linearBufferLength) { mType = type; mHandle = handle; mSap = sap; mRw = rw; mMiu = miu; mlinearBufferLength = linearBufferLength; } RegisteredSocket(int type, int handle, int sap) { mType = type; mHandle = handle; mSap = sap; } } private final BroadcastReceiver mNfcServiceReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.d(TAG, "Internal NFC Intent received"); /* LLCP Link deactivation */ if (intent.getAction().equals(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED)) { mLlcpLinkState = intent.getIntExtra(NfcAdapter.EXTRA_LLCP_LINK_STATE_CHANGED, NfcAdapter.LLCP_LINK_STATE_DEACTIVATED); if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_DEACTIVATED) { /* restart polling loop */ mManager.enableDiscovery(DISCOVERY_MODE_READER); } } /* LLCP Link activation */ else if (intent.getAction().equals( NativeNfcManager.INTERNAL_LLCP_LINK_STATE_CHANGED_ACTION)) { mLlcpLinkState = intent.getIntExtra( NativeNfcManager.INTERNAL_LLCP_LINK_STATE_CHANGED_EXTRA, NfcAdapter.LLCP_LINK_STATE_DEACTIVATED); if (mLlcpLinkState == NfcAdapter.LLCP_LINK_STATE_ACTIVATED) { /* check if sockets are registered */ ListIterator it = mRegisteredSocketList.listIterator(); Log.d(TAG, "Nb socket resgistered = " + mRegisteredSocketList.size()); while (it.hasNext()) { RegisteredSocket registeredSocket = it.next(); switch (registeredSocket.mType) { case LLCP_SERVICE_SOCKET_TYPE: Log.d(TAG, "Registered Llcp Service Socket"); NativeLlcpServiceSocket serviceSocket; serviceSocket = mManager.doCreateLlcpServiceSocket( registeredSocket.mSap, registeredSocket.mServiceName, registeredSocket.mMiu, registeredSocket.mRw, registeredSocket.mlinearBufferLength); if (serviceSocket != null) { /* Add the socket into the socket map */ mSocketMap.put(registeredSocket.mHandle, serviceSocket); } else { /* * socket creation error - update the socket * handle counter */ mGeneratedSocketHandle -= 1; } break; case LLCP_SOCKET_TYPE: Log.d(TAG, "Registered Llcp Socket"); NativeLlcpSocket clientSocket; clientSocket = mManager.doCreateLlcpSocket(registeredSocket.mSap, registeredSocket.mMiu, registeredSocket.mRw, registeredSocket.mlinearBufferLength); if (clientSocket != null) { /* Add the socket into the socket map */ mSocketMap.put(registeredSocket.mHandle, clientSocket); } else { /* * socket creation error - update the socket * handle counter */ mGeneratedSocketHandle -= 1; } break; case LLCP_CONNECTIONLESS_SOCKET_TYPE: Log.d(TAG, "Registered Llcp Connectionless Socket"); NativeLlcpConnectionlessSocket connectionlessSocket; connectionlessSocket = mManager .doCreateLlcpConnectionlessSocket(registeredSocket.mSap); if (connectionlessSocket != null) { /* Add the socket into the socket map */ mSocketMap.put(registeredSocket.mHandle, connectionlessSocket); } else { /* * socket creation error - update the socket * handle counter */ mGeneratedSocketHandle -= 1; } break; } } /* Remove all registered socket from the list */ mRegisteredSocketList.clear(); /* Broadcast Intent Link LLCP activated */ Intent LlcpLinkIntent = new Intent(); LlcpLinkIntent.setAction(NfcAdapter.ACTION_LLCP_LINK_STATE_CHANGED); LlcpLinkIntent.putExtra(NfcAdapter.EXTRA_LLCP_LINK_STATE_CHANGED, NfcAdapter.LLCP_LINK_STATE_ACTIVATED); Log.d(TAG, "Broadcasting LLCP activation"); mContext.sendOrderedBroadcast(LlcpLinkIntent, android.Manifest.permission.NFC_LLCP); } } /* Target Deactivated */ else if (intent.getAction().equals( NativeNfcManager.INTERNAL_TARGET_DESELECTED_ACTION)) { if(mOpenPending != false){ mOpenPending = false; } /* Restart polling loop for notification */ mManager.enableDiscovery(DISCOVERY_MODE_READER); } } }; }