• 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 /**
30  * Native interface to the NFC Manager functions
31  */
32 public class NativeNfcManager implements DeviceHost {
33     private static final String TAG = "NativeNfcManager";
34     static final String PREF = "NciDeviceHost";
35 
36     static final int DEFAULT_LLCP_MIU = 1980;
37     static final int DEFAULT_LLCP_RWSIZE = 2;
38 
39     static final String DRIVER_NAME = "android-nci";
40 
41     static {
42         System.loadLibrary("nfc_nci_jni");
43     }
44 
45 
46     /* Native structure */
47     private long mNative;
48 
49     private final DeviceHostListener mListener;
50     private final Context mContext;
51 
52 
NativeNfcManager(Context context, DeviceHostListener listener)53     public NativeNfcManager(Context context, DeviceHostListener listener) {
54         mListener = listener;
55         initializeNativeStructure();
56         mContext = context;
57     }
58 
initializeNativeStructure()59     public native boolean initializeNativeStructure();
60 
doDownload()61     private native boolean doDownload();
62 
doGetLastError()63     public native int doGetLastError();
64 
65     @Override
checkFirmware()66     public void checkFirmware() {
67         doDownload();
68     }
69 
doInitialize()70     private native boolean doInitialize();
71 
72     @Override
initialize()73     public boolean initialize() {
74         return doInitialize();
75     }
76 
doDeinitialize()77     private native boolean doDeinitialize();
78 
79     @Override
deinitialize()80     public boolean deinitialize() {
81         return doDeinitialize();
82     }
83 
84     @Override
getName()85     public String getName() {
86         return DRIVER_NAME;
87     }
88 
89     @Override
sendRawFrame(byte[] data)90     public native boolean sendRawFrame(byte[] data);
91 
92     @Override
routeAid(byte[] aid, int route)93     public native boolean routeAid(byte[] aid, int route);
94 
95     @Override
unrouteAid(byte[] aid)96     public native boolean unrouteAid(byte[] aid);
97 
98     @Override
commitRouting()99     public native boolean commitRouting();
100 
doEnableDiscovery(int techMask, boolean enableLowPowerPolling, boolean enableReaderMode, boolean enableHostRouting, boolean enableP2p, boolean restart)101     private native void doEnableDiscovery(int techMask,
102                                           boolean enableLowPowerPolling,
103                                           boolean enableReaderMode,
104                                           boolean enableHostRouting,
105                                           boolean enableP2p,
106                                           boolean restart);
107     @Override
enableDiscovery(NfcDiscoveryParameters params, boolean restart)108     public void enableDiscovery(NfcDiscoveryParameters params, boolean restart) {
109         doEnableDiscovery(params.getTechMask(), params.shouldEnableLowPowerDiscovery(),
110                 params.shouldEnableReaderMode(), params.shouldEnableHostRouting(),
111                 params.shouldEnableP2p(), restart);
112     }
113 
114     @Override
disableDiscovery()115     public native void disableDiscovery();
116 
doCreateLlcpConnectionlessSocket(int nSap, String sn)117     private native NativeLlcpConnectionlessSocket doCreateLlcpConnectionlessSocket(int nSap,
118             String sn);
119 
120     @Override
createLlcpConnectionlessSocket(int nSap, String sn)121     public LlcpConnectionlessSocket createLlcpConnectionlessSocket(int nSap, String sn)
122             throws LlcpException {
123         LlcpConnectionlessSocket socket = doCreateLlcpConnectionlessSocket(nSap, sn);
124         if (socket != null) {
125             return socket;
126         } else {
127             /* Get Error Status */
128             int error = doGetLastError();
129 
130             Log.d(TAG, "failed to create llcp socket: " + ErrorCodes.asString(error));
131 
132             switch (error) {
133                 case ErrorCodes.ERROR_BUFFER_TO_SMALL:
134                 case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES:
135                     throw new LlcpException(error);
136                 default:
137                     throw new LlcpException(ErrorCodes.ERROR_SOCKET_CREATION);
138             }
139         }
140     }
141 
doCreateLlcpServiceSocket(int nSap, String sn, int miu, int rw, int linearBufferLength)142     private native NativeLlcpServiceSocket doCreateLlcpServiceSocket(int nSap, String sn, int miu,
143             int rw, int linearBufferLength);
144     @Override
createLlcpServerSocket(int nSap, String sn, int miu, int rw, int linearBufferLength)145     public LlcpServerSocket createLlcpServerSocket(int nSap, String sn, int miu,
146             int rw, int linearBufferLength) throws LlcpException {
147         LlcpServerSocket socket = doCreateLlcpServiceSocket(nSap, sn, miu, rw, linearBufferLength);
148         if (socket != null) {
149             return socket;
150         } else {
151             /* Get Error Status */
152             int error = doGetLastError();
153 
154             Log.d(TAG, "failed to create llcp socket: " + ErrorCodes.asString(error));
155 
156             switch (error) {
157                 case ErrorCodes.ERROR_BUFFER_TO_SMALL:
158                 case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES:
159                     throw new LlcpException(error);
160                 default:
161                     throw new LlcpException(ErrorCodes.ERROR_SOCKET_CREATION);
162             }
163         }
164     }
165 
doCreateLlcpSocket(int sap, int miu, int rw, int linearBufferLength)166     private native NativeLlcpSocket doCreateLlcpSocket(int sap, int miu, int rw,
167             int linearBufferLength);
168     @Override
createLlcpSocket(int sap, int miu, int rw, int linearBufferLength)169     public LlcpSocket createLlcpSocket(int sap, int miu, int rw,
170             int linearBufferLength) throws LlcpException {
171         LlcpSocket socket = doCreateLlcpSocket(sap, miu, rw, linearBufferLength);
172         if (socket != null) {
173             return socket;
174         } else {
175             /* Get Error Status */
176             int error = doGetLastError();
177 
178             Log.d(TAG, "failed to create llcp socket: " + ErrorCodes.asString(error));
179 
180             switch (error) {
181                 case ErrorCodes.ERROR_BUFFER_TO_SMALL:
182                 case ErrorCodes.ERROR_INSUFFICIENT_RESOURCES:
183                     throw new LlcpException(error);
184                 default:
185                     throw new LlcpException(ErrorCodes.ERROR_SOCKET_CREATION);
186             }
187         }
188     }
189 
190     @Override
doCheckLlcp()191     public native boolean doCheckLlcp();
192 
193     @Override
doActivateLlcp()194     public native boolean doActivateLlcp();
195 
doResetTimeouts()196     private native void doResetTimeouts();
197 
198     @Override
resetTimeouts()199     public void resetTimeouts() {
200         doResetTimeouts();
201     }
202 
203     @Override
doAbort()204     public native void doAbort();
205 
doSetTimeout(int tech, int timeout)206     private native boolean doSetTimeout(int tech, int timeout);
207     @Override
setTimeout(int tech, int timeout)208     public boolean setTimeout(int tech, int timeout) {
209         return doSetTimeout(tech, timeout);
210     }
211 
doGetTimeout(int tech)212     private native int doGetTimeout(int tech);
213     @Override
getTimeout(int tech)214     public int getTimeout(int tech) {
215         return doGetTimeout(tech);
216     }
217 
218 
219     @Override
canMakeReadOnly(int ndefType)220     public boolean canMakeReadOnly(int ndefType) {
221         return (ndefType == Ndef.TYPE_1 || ndefType == Ndef.TYPE_2);
222     }
223 
224     @Override
getMaxTransceiveLength(int technology)225     public int getMaxTransceiveLength(int technology) {
226         switch (technology) {
227             case (TagTechnology.NFC_A):
228             case (TagTechnology.MIFARE_CLASSIC):
229             case (TagTechnology.MIFARE_ULTRALIGHT):
230                 return 253; // PN544 RF buffer = 255 bytes, subtract two for CRC
231             case (TagTechnology.NFC_B):
232                 /////////////////////////////////////////////////////////////////
233                 // Broadcom: Since BCM2079x supports this, set NfcB max size.
234                 //return 0; // PN544 does not support transceive of raw NfcB
235                 return 253; // PN544 does not support transceive of raw NfcB
236             case (TagTechnology.NFC_V):
237                 return 253; // PN544 RF buffer = 255 bytes, subtract two for CRC
238             case (TagTechnology.ISO_DEP):
239                 /* The maximum length of a normal IsoDep frame consists of:
240                  * CLA, INS, P1, P2, LC, LE + 255 payload bytes = 261 bytes
241                  * such a frame is supported. Extended length frames however
242                  * are not supported.
243                  */
244                 return 261; // Will be automatically split in two frames on the RF layer
245             case (TagTechnology.NFC_F):
246                 return 252; // PN544 RF buffer = 255 bytes, subtract one for SoD, two for CRC
247             default:
248                 return 0;
249         }
250 
251     }
252 
doSetP2pInitiatorModes(int modes)253     private native void doSetP2pInitiatorModes(int modes);
254     @Override
setP2pInitiatorModes(int modes)255     public void setP2pInitiatorModes(int modes) {
256         doSetP2pInitiatorModes(modes);
257     }
258 
doSetP2pTargetModes(int modes)259     private native void doSetP2pTargetModes(int modes);
260     @Override
setP2pTargetModes(int modes)261     public void setP2pTargetModes(int modes) {
262         doSetP2pTargetModes(modes);
263     }
264 
265     @Override
getExtendedLengthApdusSupported()266     public boolean getExtendedLengthApdusSupported() {
267         // TODO check BCM support
268         return false;
269     }
270 
271     @Override
getDefaultLlcpMiu()272     public int getDefaultLlcpMiu() {
273         return DEFAULT_LLCP_MIU;
274     }
275 
276     @Override
getDefaultLlcpRwSize()277     public int getDefaultLlcpRwSize() {
278         return DEFAULT_LLCP_RWSIZE;
279     }
280 
doDump()281     private native String doDump();
282     @Override
dump()283     public String dump() {
284         return doDump();
285     }
286 
doEnableScreenOffSuspend()287     private native void doEnableScreenOffSuspend();
288     @Override
enableScreenOffSuspend()289     public boolean enableScreenOffSuspend() {
290         doEnableScreenOffSuspend();
291         return true;
292     }
293 
doDisableScreenOffSuspend()294     private native void doDisableScreenOffSuspend();
295     @Override
disableScreenOffSuspend()296     public boolean disableScreenOffSuspend() {
297         doDisableScreenOffSuspend();
298         return true;
299     }
300 
301     /**
302      * Notifies Ndef Message (TODO: rename into notifyTargetDiscovered)
303      */
notifyNdefMessageListeners(NativeNfcTag tag)304     private void notifyNdefMessageListeners(NativeNfcTag tag) {
305         mListener.onRemoteEndpointDiscovered(tag);
306     }
307 
308     /**
309      * Notifies P2P Device detected, to activate LLCP link
310      */
notifyLlcpLinkActivation(NativeP2pDevice device)311     private void notifyLlcpLinkActivation(NativeP2pDevice device) {
312         mListener.onLlcpLinkActivated(device);
313     }
314 
315     /**
316      * Notifies P2P Device detected, to activate LLCP link
317      */
notifyLlcpLinkDeactivated(NativeP2pDevice device)318     private void notifyLlcpLinkDeactivated(NativeP2pDevice device) {
319         mListener.onLlcpLinkDeactivated(device);
320     }
321 
322     /**
323      * Notifies first packet received from remote LLCP
324      */
notifyLlcpLinkFirstPacketReceived(NativeP2pDevice device)325     private void notifyLlcpLinkFirstPacketReceived(NativeP2pDevice device) {
326         mListener.onLlcpFirstPacketReceived(device);
327     }
328 
notifyHostEmuActivated()329     private void notifyHostEmuActivated() {
330         mListener.onHostCardEmulationActivated();
331     }
332 
notifyHostEmuData(byte[] data)333     private void notifyHostEmuData(byte[] data) {
334         mListener.onHostCardEmulationData(data);
335     }
336 
notifyHostEmuDeactivated()337     private void notifyHostEmuDeactivated() {
338         mListener.onHostCardEmulationDeactivated();
339     }
340 
notifyRfFieldActivated()341     private void notifyRfFieldActivated() {
342         mListener.onRemoteFieldActivated();
343     }
344 
notifyRfFieldDeactivated()345     private void notifyRfFieldDeactivated() {
346         mListener.onRemoteFieldDeactivated();
347     }
348 
349 }
350