• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.nfc.dhimpl;
18 
19 import android.content.Context;
20 import android.nfc.ErrorCodes;
21 import android.nfc.tech.Ndef;
22 import android.nfc.tech.TagTechnology;
23 import android.util.Log;
24 
25 import com.android.nfc.DeviceHost;
26 import com.android.nfc.LlcpException;
27 import com.android.nfc.NfcDiscoveryParameters;
28 
29 import java.io.FileDescriptor;
30 import java.util.Arrays;
31 import java.util.HashMap;
32 import java.util.Iterator;
33 
34 /** Native interface to the NFC Manager functions */
35 public class NativeNfcManager implements DeviceHost {
36     private static final String TAG = "NativeNfcManager";
37     static final String PREF = "NciDeviceHost";
38 
39     static final int DEFAULT_LLCP_MIU = 1980;
40     static final int DEFAULT_LLCP_RWSIZE = 2;
41 
42     static final String DRIVER_NAME = "android-nci";
43 
44     static {
45         System.loadLibrary("nfc_nci_jni");
46     }
47 
48     /* Native structure */
49     private long mNative;
50 
51     private int mIsoDepMaxTransceiveLength;
52     private final DeviceHostListener mListener;
53     private final Context mContext;
54 
55     private final Object mLock = new Object();
56     private final HashMap<Integer, byte[]> mT3tIdentifiers = new HashMap<Integer, byte[]>();
57 
NativeNfcManager(Context context, DeviceHostListener listener)58     public NativeNfcManager(Context context, DeviceHostListener listener) {
59         mListener = listener;
60         initializeNativeStructure();
61         mContext = context;
62     }
63 
initializeNativeStructure()64     public native boolean initializeNativeStructure();
65 
doDownload()66     private native boolean doDownload();
67 
doGetLastError()68     public native int doGetLastError();
69 
70     @Override
checkFirmware()71     public boolean checkFirmware() {
72         return doDownload();
73     }
74 
doInitialize()75     private native boolean doInitialize();
76 
getIsoDepMaxTransceiveLength()77     private native int getIsoDepMaxTransceiveLength();
78 
79     @Override
initialize()80     public boolean initialize() {
81         boolean ret = doInitialize();
82         mIsoDepMaxTransceiveLength = getIsoDepMaxTransceiveLength();
83         return ret;
84     }
85 
doEnableDtaMode()86     private native void doEnableDtaMode();
87 
88     @Override
enableDtaMode()89     public void enableDtaMode() {
90         doEnableDtaMode();
91     }
92 
doDisableDtaMode()93     private native void doDisableDtaMode();
94 
95     @Override
disableDtaMode()96     public void disableDtaMode() {
97         Log.d(TAG, "disableDtaMode : entry");
98         doDisableDtaMode();
99     }
100 
doFactoryReset()101     private native void doFactoryReset();
102 
103     @Override
factoryReset()104     public void factoryReset() {
105         doFactoryReset();
106     }
107 
doShutdown()108     private native void doShutdown();
109 
110     @Override
shutdown()111     public void shutdown() {
112         doShutdown();
113     }
114 
doDeinitialize()115     private native boolean doDeinitialize();
116 
117     @Override
deinitialize()118     public boolean deinitialize() {
119         return doDeinitialize();
120     }
121 
122     @Override
getName()123     public String getName() {
124         return DRIVER_NAME;
125     }
126 
127     @Override
sendRawFrame(byte[] data)128     public native boolean sendRawFrame(byte[] data);
129 
130     @Override
routeAid(byte[] aid, int route, int aidInfo, int power)131     public native boolean routeAid(byte[] aid, int route, int aidInfo, int power);
132 
133     @Override
unrouteAid(byte[] aid)134     public native boolean unrouteAid(byte[] aid);
135 
136     @Override
commitRouting()137     public native boolean commitRouting();
138 
doRegisterT3tIdentifier(byte[] t3tIdentifier)139     public native int doRegisterT3tIdentifier(byte[] t3tIdentifier);
140 
141     @Override
registerT3tIdentifier(byte[] t3tIdentifier)142     public void registerT3tIdentifier(byte[] t3tIdentifier) {
143         synchronized (mLock) {
144             int handle = doRegisterT3tIdentifier(t3tIdentifier);
145             if (handle != 0xffff) {
146                 mT3tIdentifiers.put(Integer.valueOf(handle), t3tIdentifier);
147             }
148         }
149     }
150 
doDeregisterT3tIdentifier(int handle)151     public native void doDeregisterT3tIdentifier(int handle);
152 
153     @Override
deregisterT3tIdentifier(byte[] t3tIdentifier)154     public void deregisterT3tIdentifier(byte[] t3tIdentifier) {
155         synchronized (mLock) {
156             Iterator<Integer> it = mT3tIdentifiers.keySet().iterator();
157             while (it.hasNext()) {
158                 int handle = it.next().intValue();
159                 byte[] value = mT3tIdentifiers.get(handle);
160                 if (Arrays.equals(value, t3tIdentifier)) {
161                     doDeregisterT3tIdentifier(handle);
162                     mT3tIdentifiers.remove(handle);
163                     break;
164                 }
165             }
166         }
167     }
168 
169     @Override
clearT3tIdentifiersCache()170     public void clearT3tIdentifiersCache() {
171         synchronized (mLock) {
172             mT3tIdentifiers.clear();
173         }
174     }
175 
176     @Override
getLfT3tMax()177     public native int getLfT3tMax();
178 
179     @Override
doSetScreenState(int screen_state_mask)180     public native void doSetScreenState(int screen_state_mask);
181 
182     @Override
getNciVersion()183     public native int getNciVersion();
184 
doEnableDiscovery( int techMask, boolean enableLowPowerPolling, boolean enableReaderMode, boolean enableHostRouting, boolean enableP2p, boolean restart)185     private native void doEnableDiscovery(
186             int techMask,
187             boolean enableLowPowerPolling,
188             boolean enableReaderMode,
189             boolean enableHostRouting,
190             boolean enableP2p,
191             boolean restart);
192 
193     @Override
enableDiscovery(NfcDiscoveryParameters params, boolean restart)194     public void enableDiscovery(NfcDiscoveryParameters params, boolean restart) {
195         doEnableDiscovery(
196                 params.getTechMask(),
197                 params.shouldEnableLowPowerDiscovery(),
198                 params.shouldEnableReaderMode(),
199                 params.shouldEnableHostRouting(),
200                 params.shouldEnableP2p(),
201                 restart);
202     }
203 
204     @Override
disableDiscovery()205     public native void disableDiscovery();
206 
doCreateLlcpConnectionlessSocket( int nSap, String sn)207     private native NativeLlcpConnectionlessSocket doCreateLlcpConnectionlessSocket(
208             int nSap, String sn);
209 
210     @Override
createLlcpConnectionlessSocket(int nSap, String sn)211     public LlcpConnectionlessSocket createLlcpConnectionlessSocket(int nSap, String sn)
212             throws LlcpException {
213         LlcpConnectionlessSocket socket = doCreateLlcpConnectionlessSocket(nSap, sn);
214         if (socket != null) {
215             return socket;
216         } else {
217             /* Get Error Status */
218             int error = doGetLastError();
219 
220             Log.d(TAG, "failed to create llcp socket: " + ErrorCodes.asString(error));
221 
222             switch (error) {
223                 case ErrorCodes.ERROR_BUFFER_TO_SMALL:
224                 case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES:
225                     throw new LlcpException(error);
226                 default:
227                     throw new LlcpException(ErrorCodes.ERROR_SOCKET_CREATION);
228             }
229         }
230     }
231 
doCreateLlcpServiceSocket( int nSap, String sn, int miu, int rw, int linearBufferLength)232     private native NativeLlcpServiceSocket doCreateLlcpServiceSocket(
233             int nSap, String sn, int miu, int rw, int linearBufferLength);
234 
235     @Override
createLlcpServerSocket( int nSap, String sn, int miu, int rw, int linearBufferLength)236     public LlcpServerSocket createLlcpServerSocket(
237             int nSap, String sn, int miu, int rw, int linearBufferLength) throws LlcpException {
238         LlcpServerSocket socket = doCreateLlcpServiceSocket(nSap, sn, miu, rw, linearBufferLength);
239         if (socket != null) {
240             return socket;
241         } else {
242             /* Get Error Status */
243             int error = doGetLastError();
244 
245             Log.d(TAG, "failed to create llcp socket: " + ErrorCodes.asString(error));
246 
247             switch (error) {
248                 case ErrorCodes.ERROR_BUFFER_TO_SMALL:
249                 case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES:
250                     throw new LlcpException(error);
251                 default:
252                     throw new LlcpException(ErrorCodes.ERROR_SOCKET_CREATION);
253             }
254         }
255     }
256 
doCreateLlcpSocket( int sap, int miu, int rw, int linearBufferLength)257     private native NativeLlcpSocket doCreateLlcpSocket(
258             int sap, int miu, int rw, int linearBufferLength);
259 
260     @Override
createLlcpSocket(int sap, int miu, int rw, int linearBufferLength)261     public LlcpSocket createLlcpSocket(int sap, int miu, int rw, int linearBufferLength)
262             throws LlcpException {
263         LlcpSocket socket = doCreateLlcpSocket(sap, miu, rw, linearBufferLength);
264         if (socket != null) {
265             return socket;
266         } else {
267             /* Get Error Status */
268             int error = doGetLastError();
269 
270             Log.d(TAG, "failed to create llcp socket: " + ErrorCodes.asString(error));
271 
272             switch (error) {
273                 case ErrorCodes.ERROR_BUFFER_TO_SMALL:
274                 case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES:
275                     throw new LlcpException(error);
276                 default:
277                     throw new LlcpException(ErrorCodes.ERROR_SOCKET_CREATION);
278             }
279         }
280     }
281 
282     @Override
doCheckLlcp()283     public native boolean doCheckLlcp();
284 
285     @Override
doActivateLlcp()286     public native boolean doActivateLlcp();
287 
doResetTimeouts()288     private native void doResetTimeouts();
289 
290     @Override
resetTimeouts()291     public void resetTimeouts() {
292         doResetTimeouts();
293     }
294 
295     @Override
doAbort(String msg)296     public native void doAbort(String msg);
297 
doSetTimeout(int tech, int timeout)298     private native boolean doSetTimeout(int tech, int timeout);
299 
300     @Override
setTimeout(int tech, int timeout)301     public boolean setTimeout(int tech, int timeout) {
302         return doSetTimeout(tech, timeout);
303     }
304 
doGetTimeout(int tech)305     private native int doGetTimeout(int tech);
306 
307     @Override
getTimeout(int tech)308     public int getTimeout(int tech) {
309         return doGetTimeout(tech);
310     }
311 
312     @Override
canMakeReadOnly(int ndefType)313     public boolean canMakeReadOnly(int ndefType) {
314         return (ndefType == Ndef.TYPE_1 || ndefType == Ndef.TYPE_2);
315     }
316 
317     @Override
getMaxTransceiveLength(int technology)318     public int getMaxTransceiveLength(int technology) {
319         switch (technology) {
320             case (TagTechnology.NFC_A):
321             case (TagTechnology.MIFARE_CLASSIC):
322             case (TagTechnology.MIFARE_ULTRALIGHT):
323                 return 253; // PN544 RF buffer = 255 bytes, subtract two for CRC
324             case (TagTechnology.NFC_B):
325                 /////////////////////////////////////////////////////////////////
326                 // Broadcom: Since BCM2079x supports this, set NfcB max size.
327                 // return 0; // PN544 does not support transceive of raw NfcB
328                 return 253; // PN544 does not support transceive of raw NfcB
329             case (TagTechnology.NFC_V):
330                 return 253; // PN544 RF buffer = 255 bytes, subtract two for CRC
331             case (TagTechnology.ISO_DEP):
332                 return mIsoDepMaxTransceiveLength;
333             case (TagTechnology.NFC_F):
334                 return 255;
335             default:
336                 return 0;
337         }
338     }
339 
getAidTableSize()340     public native int getAidTableSize();
341 
doSetP2pInitiatorModes(int modes)342     private native void doSetP2pInitiatorModes(int modes);
343 
344     @Override
setP2pInitiatorModes(int modes)345     public void setP2pInitiatorModes(int modes) {
346         doSetP2pInitiatorModes(modes);
347     }
348 
doSetP2pTargetModes(int modes)349     private native void doSetP2pTargetModes(int modes);
350 
351     @Override
setP2pTargetModes(int modes)352     public void setP2pTargetModes(int modes) {
353         doSetP2pTargetModes(modes);
354     }
355 
356     @Override
getExtendedLengthApdusSupported()357     public boolean getExtendedLengthApdusSupported() {
358         /* 261 is the default size if extended length frames aren't supported */
359         if (getMaxTransceiveLength(TagTechnology.ISO_DEP) > 261) return true;
360         return false;
361     }
362 
363     @Override
getDefaultLlcpMiu()364     public int getDefaultLlcpMiu() {
365         return DEFAULT_LLCP_MIU;
366     }
367 
368     @Override
getDefaultLlcpRwSize()369     public int getDefaultLlcpRwSize() {
370         return DEFAULT_LLCP_RWSIZE;
371     }
372 
doDump(FileDescriptor fd)373     private native void doDump(FileDescriptor fd);
374 
375     @Override
dump(FileDescriptor fd)376     public void dump(FileDescriptor fd) {
377         doDump(fd);
378     }
379 
doEnableScreenOffSuspend()380     private native void doEnableScreenOffSuspend();
381 
382     @Override
enableScreenOffSuspend()383     public boolean enableScreenOffSuspend() {
384         doEnableScreenOffSuspend();
385         return true;
386     }
387 
doDisableScreenOffSuspend()388     private native void doDisableScreenOffSuspend();
389 
390     @Override
disableScreenOffSuspend()391     public boolean disableScreenOffSuspend() {
392         doDisableScreenOffSuspend();
393         return true;
394     }
395 
doSetNfcSecure(boolean enable)396     private native boolean doSetNfcSecure(boolean enable);
397 
398     @Override
setNfcSecure(boolean enable)399     public boolean setNfcSecure(boolean enable) {
400         return doSetNfcSecure(enable);
401     }
402 
403     @Override
getNfaStorageDir()404     public native String getNfaStorageDir();
405 
doStartStopPolling(boolean start)406     private native void doStartStopPolling(boolean start);
407 
408     @Override
startStopPolling(boolean start)409     public void startStopPolling(boolean start) {
410         doStartStopPolling(start);
411     }
412 
doSetNfceePowerAndLinkCtrl(boolean enable)413     private native void doSetNfceePowerAndLinkCtrl(boolean enable);
414 
415     @Override
setNfceePowerAndLinkCtrl(boolean enable)416     public void setNfceePowerAndLinkCtrl(boolean enable) {
417         doSetNfceePowerAndLinkCtrl(enable);
418     }
419 
420     @Override
getRoutingTable()421     public native byte[] getRoutingTable();
422 
423     @Override
getMaxRoutingTableSize()424     public native int getMaxRoutingTableSize();
425 
426     /** Notifies Ndef Message (TODO: rename into notifyTargetDiscovered) */
notifyNdefMessageListeners(NativeNfcTag tag)427     private void notifyNdefMessageListeners(NativeNfcTag tag) {
428         mListener.onRemoteEndpointDiscovered(tag);
429     }
430 
431     /** Notifies P2P Device detected, to activate LLCP link */
notifyLlcpLinkActivation(NativeP2pDevice device)432     private void notifyLlcpLinkActivation(NativeP2pDevice device) {
433         mListener.onLlcpLinkActivated(device);
434     }
435 
436     /** Notifies P2P Device detected, to activate LLCP link */
notifyLlcpLinkDeactivated(NativeP2pDevice device)437     private void notifyLlcpLinkDeactivated(NativeP2pDevice device) {
438         mListener.onLlcpLinkDeactivated(device);
439     }
440 
441     /** Notifies first packet received from remote LLCP */
notifyLlcpLinkFirstPacketReceived(NativeP2pDevice device)442     private void notifyLlcpLinkFirstPacketReceived(NativeP2pDevice device) {
443         mListener.onLlcpFirstPacketReceived(device);
444     }
445 
notifyHostEmuActivated(int technology)446     private void notifyHostEmuActivated(int technology) {
447         mListener.onHostCardEmulationActivated(technology);
448     }
449 
notifyHostEmuData(int technology, byte[] data)450     private void notifyHostEmuData(int technology, byte[] data) {
451         mListener.onHostCardEmulationData(technology, data);
452     }
453 
notifyHostEmuDeactivated(int technology)454     private void notifyHostEmuDeactivated(int technology) {
455         mListener.onHostCardEmulationDeactivated(technology);
456     }
457 
notifyRfFieldActivated()458     private void notifyRfFieldActivated() {
459         mListener.onRemoteFieldActivated();
460     }
461 
notifyRfFieldDeactivated()462     private void notifyRfFieldDeactivated() {
463         mListener.onRemoteFieldDeactivated();
464     }
465 
notifyTransactionListeners(byte[] aid, byte[] data, String evtSrc)466     private void notifyTransactionListeners(byte[] aid, byte[] data, String evtSrc) {
467         mListener.onNfcTransactionEvent(aid, data, evtSrc);
468     }
469 
notifyEeUpdated()470     private void notifyEeUpdated() {
471         mListener.onEeUpdated();
472     }
473 
notifyHwErrorReported()474     private void notifyHwErrorReported() {
475         mListener.onHwErrorReported();
476     }
477 }
478