• 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 #include <errno.h>
18 #include <pthread.h>
19 #include <semaphore.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <math.h>
23 #include <sys/queue.h>
24 #include <hardware/hardware.h>
25 #include <hardware/nfc.h>
26 #include <cutils/properties.h>
27 #include <ScopedLocalRef.h>
28 
29 #include "com_android_nfc.h"
30 
31 #define ERROR_BUFFER_TOO_SMALL       -12
32 #define ERROR_INSUFFICIENT_RESOURCES -9
33 
34 extern uint32_t libnfc_llc_error_count;
35 
36 static phLibNfc_sConfig_t   gDrvCfg;
37 void   *gHWRef;
38 static phNfc_sData_t gInputParam;
39 static phNfc_sData_t gOutputParam;
40 
41 uint8_t device_connected_flag;
42 static bool driverConfigured = FALSE;
43 
44 static phLibNfc_Handle              hLlcpHandle;
45 static NFCSTATUS                    lastErrorStatus = NFCSTATUS_FAILED;
46 static phLibNfc_Llcp_eLinkStatus_t  g_eLinkStatus = phFriNfc_LlcpMac_eLinkDefault;
47 
48 static jmethodID cached_NfcManager_notifyNdefMessageListeners;
49 static jmethodID cached_NfcManager_notifyTransactionListeners;
50 static jmethodID cached_NfcManager_notifyLlcpLinkActivation;
51 static jmethodID cached_NfcManager_notifyLlcpLinkDeactivated;
52 static jmethodID cached_NfcManager_notifyTargetDeselected;
53 
54 static jmethodID cached_NfcManager_notifySeFieldActivated;
55 static jmethodID cached_NfcManager_notifySeFieldDeactivated;
56 
57 static jmethodID cached_NfcManager_notifySeApduReceived;
58 static jmethodID cached_NfcManager_notifySeMifareAccess;
59 static jmethodID cached_NfcManager_notifySeEmvCardRemoval;
60 
61 namespace android {
62 
63 phLibNfc_Handle     storedHandle = 0;
64 
65 struct nfc_jni_native_data *exported_nat = NULL;
66 
67 /* Internal functions declaration */
68 static void *nfc_jni_client_thread(void *arg);
69 static void nfc_jni_init_callback(void *pContext, NFCSTATUS status);
70 static void nfc_jni_deinit_callback(void *pContext, NFCSTATUS status);
71 static void nfc_jni_discover_callback(void *pContext, NFCSTATUS status);
72 static void nfc_jni_se_set_mode_callback(void *context,
73         phLibNfc_Handle handle, NFCSTATUS status);
74 static void nfc_jni_llcpcfg_callback(void *pContext, NFCSTATUS status);
75 static void nfc_jni_start_discovery_locked(struct nfc_jni_native_data *nat, bool resume);
76 static void nfc_jni_Discovery_notification_callback(void *pContext,
77         phLibNfc_RemoteDevList_t *psRemoteDevList,
78         uint8_t uNofRemoteDev, NFCSTATUS status);
79 static void nfc_jni_transaction_callback(void *context,
80         phLibNfc_eSE_EvtType_t evt_type, phLibNfc_Handle handle,
81         phLibNfc_uSeEvtInfo_t *evt_info, NFCSTATUS status);
82 static bool performDownload(struct nfc_jni_native_data *nat, bool takeLock);
83 
84 extern void set_target_activationBytes(JNIEnv *e, jobject tag,
85         phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo);
86 extern void set_target_pollBytes(JNIEnv *e, jobject tag,
87         phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo);
88 
89 /*
90  * Deferred callback called when client thread must be exited
91  */
client_kill_deferred_call(void * arg)92 static void client_kill_deferred_call(void* arg)
93 {
94    struct nfc_jni_native_data *nat = (struct nfc_jni_native_data *)arg;
95 
96    nat->running = FALSE;
97 }
98 
kill_client(nfc_jni_native_data * nat)99 static void kill_client(nfc_jni_native_data *nat)
100 {
101    phDal4Nfc_Message_Wrapper_t  wrapper;
102    phLibNfc_DeferredCall_t     *pMsg;
103 
104    usleep(50000);
105 
106    ALOGD("Terminating client thread...");
107 
108    pMsg = (phLibNfc_DeferredCall_t*)malloc(sizeof(phLibNfc_DeferredCall_t));
109    pMsg->pCallback = client_kill_deferred_call;
110    pMsg->pParameter = (void*)nat;
111 
112    wrapper.msg.eMsgType = PH_LIBNFC_DEFERREDCALL_MSG;
113    wrapper.msg.pMsgData = pMsg;
114    wrapper.msg.Size     = sizeof(phLibNfc_DeferredCall_t);
115 
116    phDal4Nfc_msgsnd(gDrvCfg.nClientId, (struct msgbuf *)&wrapper, sizeof(phLibNfc_Message_t), 0);
117 }
118 
nfc_jni_ioctl_callback(void * pContext,phNfc_sData_t * pOutput,NFCSTATUS status)119 static void nfc_jni_ioctl_callback(void *pContext, phNfc_sData_t *pOutput, NFCSTATUS status) {
120    struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext;
121    LOG_CALLBACK("nfc_jni_ioctl_callback", status);
122 
123    /* Report the callback status and wake up the caller */
124    pCallbackData->status = status;
125    sem_post(&pCallbackData->sem);
126 }
127 
nfc_jni_deinit_download_callback(void * pContext,NFCSTATUS status)128 static void nfc_jni_deinit_download_callback(void *pContext, NFCSTATUS status)
129 {
130    struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext;
131    LOG_CALLBACK("nfc_jni_deinit_download_callback", status);
132 
133    /* Report the callback status and wake up the caller */
134    pCallbackData->status = status;
135    sem_post(&pCallbackData->sem);
136 }
137 
nfc_jni_download_locked(struct nfc_jni_native_data * nat,uint8_t update)138 static int nfc_jni_download_locked(struct nfc_jni_native_data *nat, uint8_t update)
139 {
140     uint8_t OutputBuffer[1];
141     uint8_t InputBuffer[1];
142     struct timespec ts;
143     NFCSTATUS status = NFCSTATUS_FAILED;
144     phLibNfc_StackCapabilities_t caps;
145     struct nfc_jni_callback_data cb_data;
146     bool result;
147 
148     /* Create the local semaphore */
149     if (!nfc_cb_data_init(&cb_data, NULL))
150     {
151        goto clean_and_return;
152     }
153 
154     if(update)
155     {
156         //deinit
157         TRACE("phLibNfc_Mgt_DeInitialize() (download)");
158         REENTRANCE_LOCK();
159         status = phLibNfc_Mgt_DeInitialize(gHWRef, nfc_jni_deinit_download_callback, (void *)&cb_data);
160         REENTRANCE_UNLOCK();
161         if (status != NFCSTATUS_PENDING)
162         {
163             ALOGE("phLibNfc_Mgt_DeInitialize() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
164         }
165 
166         clock_gettime(CLOCK_REALTIME, &ts);
167         ts.tv_sec += 5;
168 
169         /* Wait for callback response */
170         if(sem_timedwait(&cb_data.sem, &ts))
171         {
172             ALOGW("Deinitialization timed out (download)");
173         }
174 
175         if(cb_data.status != NFCSTATUS_SUCCESS)
176         {
177             ALOGW("Deinitialization FAILED (download)");
178         }
179         TRACE("Deinitialization SUCCESS (download)");
180     }
181 
182     result = performDownload(nat, false);
183 
184     if (!result) {
185         status = NFCSTATUS_FAILED;
186         goto clean_and_return;
187     }
188 
189     TRACE("phLibNfc_Mgt_Initialize()");
190     REENTRANCE_LOCK();
191     status = phLibNfc_Mgt_Initialize(gHWRef, nfc_jni_init_callback, (void *)&cb_data);
192     REENTRANCE_UNLOCK();
193     if(status != NFCSTATUS_PENDING)
194     {
195         ALOGE("phLibNfc_Mgt_Initialize() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
196         goto clean_and_return;
197     }
198     TRACE("phLibNfc_Mgt_Initialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
199 
200     if(sem_wait(&cb_data.sem))
201     {
202        ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
203        status = NFCSTATUS_FAILED;
204        goto clean_and_return;
205     }
206 
207     /* Initialization Status */
208     if(cb_data.status != NFCSTATUS_SUCCESS)
209     {
210         status = cb_data.status;
211         goto clean_and_return;
212     }
213 
214     /* ====== CAPABILITIES ======= */
215     REENTRANCE_LOCK();
216     status = phLibNfc_Mgt_GetstackCapabilities(&caps, (void*)nat);
217     REENTRANCE_UNLOCK();
218     if (status != NFCSTATUS_SUCCESS)
219     {
220        ALOGW("phLibNfc_Mgt_GetstackCapabilities returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
221     }
222     else
223     {
224         ALOGD("NFC capabilities: HAL = %x, FW = %x, HW = %x, Model = %x, HCI = %x, Full_FW = %d, Rev = %d, FW Update Info = %d",
225               caps.psDevCapabilities.hal_version,
226               caps.psDevCapabilities.fw_version,
227               caps.psDevCapabilities.hw_version,
228               caps.psDevCapabilities.model_id,
229               caps.psDevCapabilities.hci_version,
230               caps.psDevCapabilities.full_version[NXP_FULL_VERSION_LEN-1],
231               caps.psDevCapabilities.full_version[NXP_FULL_VERSION_LEN-2],
232               caps.psDevCapabilities.firmware_update_info);
233     }
234 
235     /*Download is successful*/
236     status = NFCSTATUS_SUCCESS;
237 
238 clean_and_return:
239    nfc_cb_data_deinit(&cb_data);
240    return status;
241 }
242 
nfc_jni_configure_driver(struct nfc_jni_native_data * nat)243 static int nfc_jni_configure_driver(struct nfc_jni_native_data *nat)
244 {
245     char value[PROPERTY_VALUE_MAX];
246     int result = FALSE;
247     NFCSTATUS status;
248 
249     /* ====== CONFIGURE DRIVER ======= */
250     /* Configure hardware link */
251     gDrvCfg.nClientId = phDal4Nfc_msgget(0, 0600);
252 
253     TRACE("phLibNfc_Mgt_ConfigureDriver(0x%08x)", gDrvCfg.nClientId);
254     REENTRANCE_LOCK();
255     status = phLibNfc_Mgt_ConfigureDriver(&gDrvCfg, &gHWRef);
256     REENTRANCE_UNLOCK();
257     if(status == NFCSTATUS_ALREADY_INITIALISED) {
258            ALOGW("phLibNfc_Mgt_ConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
259     }
260     else if(status != NFCSTATUS_SUCCESS)
261     {
262         ALOGE("phLibNfc_Mgt_ConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
263         goto clean_and_return;
264     }
265     TRACE("phLibNfc_Mgt_ConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
266 
267     if(pthread_create(&(nat->thread), NULL, nfc_jni_client_thread, nat) != 0)
268     {
269         ALOGE("pthread_create failed");
270         goto clean_and_return;
271     }
272 
273     driverConfigured = TRUE;
274 
275 clean_and_return:
276     return result;
277 }
278 
nfc_jni_unconfigure_driver(struct nfc_jni_native_data * nat)279 static int nfc_jni_unconfigure_driver(struct nfc_jni_native_data *nat)
280 {
281     int result = FALSE;
282     NFCSTATUS status;
283 
284     /* Unconfigure driver */
285     TRACE("phLibNfc_Mgt_UnConfigureDriver()");
286     REENTRANCE_LOCK();
287     status = phLibNfc_Mgt_UnConfigureDriver(gHWRef);
288     REENTRANCE_UNLOCK();
289     if(status != NFCSTATUS_SUCCESS)
290     {
291         ALOGE("phLibNfc_Mgt_UnConfigureDriver() returned error 0x%04x[%s] -- this should never happen", status, nfc_jni_get_status_name( status));
292     }
293     else
294     {
295        ALOGD("phLibNfc_Mgt_UnConfigureDriver() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
296        result = TRUE;
297     }
298 
299     driverConfigured = FALSE;
300 
301     return result;
302 }
303 
304 /* Initialization function */
nfc_jni_initialize(struct nfc_jni_native_data * nat)305 static int nfc_jni_initialize(struct nfc_jni_native_data *nat) {
306    struct timespec ts;
307    uint8_t resp[16];
308    NFCSTATUS status;
309    phLibNfc_StackCapabilities_t caps;
310    phLibNfc_SE_List_t SE_List[PHLIBNFC_MAXNO_OF_SE];
311    uint8_t i, No_SE = PHLIBNFC_MAXNO_OF_SE, SmartMX_index = 0, SmartMX_detected = 0;
312    phLibNfc_Llcp_sLinkParameters_t LlcpConfigInfo;
313    struct nfc_jni_callback_data cb_data;
314    uint8_t firmware_status;
315    uint8_t update = TRUE;
316    int result = JNI_FALSE;
317    const hw_module_t* hw_module;
318    nfc_pn544_device_t* pn544_dev = NULL;
319    int ret = 0;
320    ALOGD("Start Initialization\n");
321 
322    /* Create the local semaphore */
323    if (!nfc_cb_data_init(&cb_data, NULL))
324    {
325       goto clean_and_return;
326    }
327    /* Get EEPROM values and device port from product-specific settings */
328    ret = hw_get_module(NFC_HARDWARE_MODULE_ID, &hw_module);
329    if (ret) {
330       ALOGE("hw_get_module() failed.");
331       goto clean_and_return;
332    }
333    ret = nfc_pn544_open(hw_module, &pn544_dev);
334    if (ret) {
335       ALOGE("Could not open pn544 hw_module.");
336       goto clean_and_return;
337    }
338    if (pn544_dev->num_eeprom_settings == 0 || pn544_dev->eeprom_settings == NULL) {
339        ALOGE("Could not load EEPROM settings");
340        goto clean_and_return;
341    }
342 
343    /* Reset device connected handle */
344    device_connected_flag = 0;
345 
346    /* Reset stored handle */
347    storedHandle = 0;
348 
349    /* Initialize Driver */
350    if(!driverConfigured)
351    {
352        nfc_jni_configure_driver(nat);
353    }
354 
355    /* ====== INITIALIZE ======= */
356 
357    TRACE("phLibNfc_Mgt_Initialize()");
358    REENTRANCE_LOCK();
359    status = phLibNfc_Mgt_Initialize(gHWRef, nfc_jni_init_callback, (void *)&cb_data);
360    REENTRANCE_UNLOCK();
361    if(status != NFCSTATUS_PENDING)
362    {
363       ALOGE("phLibNfc_Mgt_Initialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
364       update = FALSE;
365       goto force_download;
366    }
367    TRACE("phLibNfc_Mgt_Initialize returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
368 
369    /* Wait for callback response */
370    if(sem_wait(&cb_data.sem))
371    {
372       ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
373       goto clean_and_return;
374    }
375 
376    /* Initialization Status */
377    if(cb_data.status != NFCSTATUS_SUCCESS)
378    {
379       update = FALSE;
380       goto force_download;
381    }
382 
383    /* ====== CAPABILITIES ======= */
384 
385    REENTRANCE_LOCK();
386    status = phLibNfc_Mgt_GetstackCapabilities(&caps, (void*)nat);
387    REENTRANCE_UNLOCK();
388    if (status != NFCSTATUS_SUCCESS)
389    {
390       ALOGW("phLibNfc_Mgt_GetstackCapabilities returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
391    }
392    else
393    {
394        ALOGD("NFC capabilities: HAL = %x, FW = %x, HW = %x, Model = %x, HCI = %x, Full_FW = %d, Rev = %d, FW Update Info = %d",
395              caps.psDevCapabilities.hal_version,
396              caps.psDevCapabilities.fw_version,
397              caps.psDevCapabilities.hw_version,
398              caps.psDevCapabilities.model_id,
399              caps.psDevCapabilities.hci_version,
400              caps.psDevCapabilities.full_version[NXP_FULL_VERSION_LEN-1],
401              caps.psDevCapabilities.full_version[NXP_FULL_VERSION_LEN-2],
402              caps.psDevCapabilities.firmware_update_info);
403    }
404 
405    /* ====== FIRMWARE VERSION ======= */
406    if(caps.psDevCapabilities.firmware_update_info)
407    {
408 force_download:
409        for (i=0; i<3; i++)
410        {
411            TRACE("Firmware version not UpToDate");
412            status = nfc_jni_download_locked(nat, update);
413            if(status == NFCSTATUS_SUCCESS)
414            {
415                ALOGI("Firmware update SUCCESS");
416                break;
417            }
418            ALOGW("Firmware update FAILED");
419            update = FALSE;
420        }
421        if(i>=3)
422        {
423            ALOGE("Unable to update firmware, giving up");
424            goto clean_and_return;
425        }
426    }
427    else
428    {
429        TRACE("Firmware version UpToDate");
430    }
431    /* ====== EEPROM SETTINGS ======= */
432 
433    // Update EEPROM settings
434    TRACE("******  START EEPROM SETTINGS UPDATE ******");
435    for (i = 0; i < pn544_dev->num_eeprom_settings; i++)
436    {
437       char eeprom_property[PROPERTY_KEY_MAX];
438       char eeprom_value[PROPERTY_VALUE_MAX];
439       uint8_t* eeprom_base = &(pn544_dev->eeprom_settings[i*4]);
440       TRACE("> EEPROM SETTING: %d", i);
441 
442       // Check for override of this EEPROM value in properties
443       snprintf(eeprom_property, sizeof(eeprom_property), "debug.nfc.eeprom.%02X%02X",
444               eeprom_base[1], eeprom_base[2]);
445       TRACE(">> Checking property: %s", eeprom_property);
446       if (property_get(eeprom_property, eeprom_value, "") == 2) {
447           int eeprom_value_num = (int)strtol(eeprom_value, (char**)NULL, 16);
448           ALOGD(">> Override EEPROM addr 0x%02X%02X with value %02X",
449                   eeprom_base[1], eeprom_base[2], eeprom_value_num);
450           eeprom_base[3] = eeprom_value_num;
451       }
452 
453       TRACE(">> Addr: 0x%02X%02X set to: 0x%02X", eeprom_base[1], eeprom_base[2],
454               eeprom_base[3]);
455       gInputParam.buffer = eeprom_base;
456       gInputParam.length = 0x04;
457       gOutputParam.buffer = resp;
458 
459       REENTRANCE_LOCK();
460       status = phLibNfc_Mgt_IoCtl(gHWRef, NFC_MEM_WRITE, &gInputParam, &gOutputParam, nfc_jni_ioctl_callback, (void *)&cb_data);
461       REENTRANCE_UNLOCK();
462       if (status != NFCSTATUS_PENDING) {
463          ALOGE("phLibNfc_Mgt_IoCtl() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
464          goto clean_and_return;
465       }
466       /* Wait for callback response */
467       if(sem_wait(&cb_data.sem))
468       {
469          ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
470          goto clean_and_return;
471       }
472 
473       /* Initialization Status */
474       if (cb_data.status != NFCSTATUS_SUCCESS)
475       {
476          goto clean_and_return;
477       }
478    }
479    TRACE("******  ALL EEPROM SETTINGS UPDATED  ******");
480 
481    /* ====== SECURE ELEMENTS ======= */
482 
483    REENTRANCE_LOCK();
484    ALOGD("phLibNfc_SE_GetSecureElementList()");
485    status = phLibNfc_SE_GetSecureElementList(SE_List, &No_SE);
486    REENTRANCE_UNLOCK();
487    if (status != NFCSTATUS_SUCCESS)
488    {
489       ALOGD("phLibNfc_SE_GetSecureElementList(): Error");
490       goto clean_and_return;
491    }
492 
493    ALOGD("\n> Number of Secure Element(s) : %d\n", No_SE);
494    /* Display Secure Element information */
495    for (i = 0; i < No_SE; i++)
496    {
497       if (SE_List[i].eSE_Type == phLibNfc_SE_Type_SmartMX) {
498          ALOGD("phLibNfc_SE_GetSecureElementList(): SMX detected, handle=%p", (void*)SE_List[i].hSecureElement);
499       } else if (SE_List[i].eSE_Type == phLibNfc_SE_Type_UICC) {
500          ALOGD("phLibNfc_SE_GetSecureElementList(): UICC detected, handle=%p", (void*)SE_List[i].hSecureElement);
501       }
502 
503       /* Set SE mode - Off */
504       REENTRANCE_LOCK();
505       status = phLibNfc_SE_SetMode(SE_List[i].hSecureElement,
506             phLibNfc_SE_ActModeOff, nfc_jni_se_set_mode_callback,
507             (void *)&cb_data);
508       REENTRANCE_UNLOCK();
509       if (status != NFCSTATUS_PENDING)
510       {
511          ALOGE("phLibNfc_SE_SetMode() returned 0x%04x[%s]", status,
512                nfc_jni_get_status_name(status));
513          goto clean_and_return;
514       }
515       ALOGD("phLibNfc_SE_SetMode() returned 0x%04x[%s]", status,
516             nfc_jni_get_status_name(status));
517 
518       /* Wait for callback response */
519       if(sem_wait(&cb_data.sem))
520       {
521          ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
522          goto clean_and_return;
523       }
524    }
525 
526    /* ====== LLCP ======= */
527 
528    /* LLCP Params */
529    TRACE("******  NFC Config Mode NFCIP1 - LLCP ******");
530    LlcpConfigInfo.miu    = nat->miu;
531    LlcpConfigInfo.lto    = nat->lto;
532    LlcpConfigInfo.wks    = nat->wks;
533    LlcpConfigInfo.option = nat->opt;
534 
535    REENTRANCE_LOCK();
536    status = phLibNfc_Mgt_SetLlcp_ConfigParams(&LlcpConfigInfo,
537                                               nfc_jni_llcpcfg_callback,
538                                               (void *)&cb_data);
539    REENTRANCE_UNLOCK();
540    if(status != NFCSTATUS_PENDING)
541    {
542       ALOGE("phLibNfc_Mgt_SetLlcp_ConfigParams returned 0x%04x[%s]", status,
543            nfc_jni_get_status_name(status));
544       goto clean_and_return;
545    }
546    TRACE("phLibNfc_Mgt_SetLlcp_ConfigParams returned 0x%04x[%s]", status,
547          nfc_jni_get_status_name(status));
548 
549    /* Wait for callback response */
550    if(sem_wait(&cb_data.sem))
551    {
552       ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
553       goto clean_and_return;
554    }
555 
556    /* ===== DISCOVERY ==== */
557    nat->discovery_cfg.NfcIP_Mode = nat->p2p_initiator_modes;  //initiator
558    nat->discovery_cfg.NfcIP_Target_Mode = nat->p2p_target_modes;  //target
559    nat->discovery_cfg.Duration = 300000; /* in ms */
560    nat->discovery_cfg.NfcIP_Tgt_Disable = FALSE;
561 
562    /* Register for the card emulation mode */
563    REENTRANCE_LOCK();
564    ret = phLibNfc_SE_NtfRegister(nfc_jni_transaction_callback,(void *)nat);
565    REENTRANCE_UNLOCK();
566    if(ret != NFCSTATUS_SUCCESS)
567    {
568         ALOGD("phLibNfc_SE_NtfRegister returned 0x%02x",ret);
569         goto clean_and_return;
570    }
571    TRACE("phLibNfc_SE_NtfRegister returned 0x%x\n", ret);
572 
573 
574    /* ====== END ======= */
575 
576    ALOGI("NFC Initialized");
577 
578    result = TRUE;
579 
580 clean_and_return:
581    if (result != TRUE)
582    {
583       if(nat)
584       {
585          kill_client(nat);
586       }
587    }
588    if (pn544_dev != NULL) {
589        nfc_pn544_close(pn544_dev);
590    }
591    nfc_cb_data_deinit(&cb_data);
592 
593    return result;
594 }
595 
is_user_build()596 static int is_user_build() {
597     char value[PROPERTY_VALUE_MAX];
598     property_get("ro.build.type", value, "");
599     return !strncmp("user", value, PROPERTY_VALUE_MAX);
600 }
601 
602 /*
603  * Last-chance fallback when there is no clean way to recover
604  * Performs a software reset
605   */
emergency_recovery(struct nfc_jni_native_data * nat)606 void emergency_recovery(struct nfc_jni_native_data *nat) {
607    if (is_user_build()) {
608        ALOGE("emergency_recovery: force restart of NFC service");
609    } else {
610        // dont recover immediately, so we can debug
611        unsigned int t;
612        for (t=1; t < 1000000; t <<= 1) {
613            ALOGE("emergency_recovery: NFC stack dead-locked");
614            sleep(t);
615        }
616    }
617    phLibNfc_Mgt_Recovery();
618    abort();  // force a noisy crash
619 }
620 
nfc_jni_reset_timeout_values()621 void nfc_jni_reset_timeout_values()
622 {
623     REENTRANCE_LOCK();
624     phLibNfc_SetIsoXchgTimeout(NXP_ISO_XCHG_TIMEOUT);
625     phLibNfc_SetHciTimeout(NXP_NFC_HCI_TIMEOUT);
626     phLibNfc_SetFelicaTimeout(NXP_FELICA_XCHG_TIMEOUT);
627     phLibNfc_SetMifareRawTimeout(NXP_MIFARE_XCHG_TIMEOUT);
628     REENTRANCE_UNLOCK();
629 }
630 
631 /*
632  * Restart the polling loop when unable to perform disconnect
633   */
nfc_jni_restart_discovery_locked(struct nfc_jni_native_data * nat)634 void nfc_jni_restart_discovery_locked(struct nfc_jni_native_data *nat)
635 {
636     nfc_jni_start_discovery_locked(nat, true);
637 }
638 
639  /*
640   *  Utility to recover UID from target infos
641   */
get_target_uid(phLibNfc_sRemoteDevInformation_t * psRemoteDevInfo)642 static phNfc_sData_t get_target_uid(phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo)
643 {
644     phNfc_sData_t uid;
645 
646     switch(psRemoteDevInfo->RemDevType)
647     {
648     case phNfc_eISO14443_A_PICC:
649     case phNfc_eISO14443_4A_PICC:
650     case phNfc_eISO14443_3A_PICC:
651     case phNfc_eMifare_PICC:
652         uid.buffer = psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Uid;
653         uid.length = psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.UidLength;
654         break;
655     case phNfc_eISO14443_B_PICC:
656     case phNfc_eISO14443_4B_PICC:
657         uid.buffer = psRemoteDevInfo->RemoteDevInfo.Iso14443B_Info.AtqB.AtqResInfo.Pupi;
658         uid.length = sizeof(psRemoteDevInfo->RemoteDevInfo.Iso14443B_Info.AtqB.AtqResInfo.Pupi);
659         break;
660     case phNfc_eFelica_PICC:
661         uid.buffer = psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm;
662         uid.length = psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDmLength;
663         break;
664     case phNfc_eJewel_PICC:
665         uid.buffer = psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid;
666         uid.length = psRemoteDevInfo->RemoteDevInfo.Jewel_Info.UidLength;
667         break;
668     case phNfc_eISO15693_PICC:
669         uid.buffer = psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.Uid;
670         uid.length = psRemoteDevInfo->RemoteDevInfo.Iso15693_Info.UidLength;
671         break;
672     case phNfc_eNfcIP1_Target:
673     case phNfc_eNfcIP1_Initiator:
674         uid.buffer = psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.NFCID;
675         uid.length = psRemoteDevInfo->RemoteDevInfo.NfcIP_Info.NFCID_Length;
676         break;
677     default:
678         uid.buffer = NULL;
679         uid.length = 0;
680         break;
681     }
682 
683     return uid;
684 }
685 
686 /*
687  * NFC stack message processing
688  */
nfc_jni_client_thread(void * arg)689 static void *nfc_jni_client_thread(void *arg)
690 {
691    struct nfc_jni_native_data *nat;
692    JNIEnv *e;
693    JavaVMAttachArgs thread_args;
694    phDal4Nfc_Message_Wrapper_t wrapper;
695 
696    nat = (struct nfc_jni_native_data *)arg;
697 
698    thread_args.name = "NFC Message Loop";
699    thread_args.version = nat->env_version;
700    thread_args.group = NULL;
701 
702    nat->vm->AttachCurrentThread(&e, &thread_args);
703    pthread_setname_np(pthread_self(), "message");
704 
705    TRACE("NFC client started");
706    nat->running = TRUE;
707    while(nat->running == TRUE)
708    {
709       /* Fetch next message from the NFC stack message queue */
710       if(phDal4Nfc_msgrcv(gDrvCfg.nClientId, (void *)&wrapper,
711          sizeof(phLibNfc_Message_t), 0, 0) == -1)
712       {
713          ALOGE("NFC client received bad message");
714          continue;
715       }
716 
717       switch(wrapper.msg.eMsgType)
718       {
719          case PH_LIBNFC_DEFERREDCALL_MSG:
720          {
721             phLibNfc_DeferredCall_t *msg =
722                (phLibNfc_DeferredCall_t *)(wrapper.msg.pMsgData);
723 
724             REENTRANCE_LOCK();
725             msg->pCallback(msg->pParameter);
726             REENTRANCE_UNLOCK();
727 
728             break;
729          }
730       }
731    }
732    TRACE("NFC client stopped");
733 
734    nat->vm->DetachCurrentThread();
735 
736    return NULL;
737 }
738 
739 extern uint8_t nfc_jni_is_ndef;
740 extern uint8_t *nfc_jni_ndef_buf;
741 extern uint32_t nfc_jni_ndef_buf_len;
742 
743 static phLibNfc_sNfcIPCfg_t nfc_jni_nfcip1_cfg =
744 {
745    3,
746    { 0x46, 0x66, 0x6D }
747 };
748 
749 /*
750  * Callbacks
751  */
752 
753 /* P2P - LLCP callbacks */
nfc_jni_llcp_linkStatus_callback(void * pContext,phFriNfc_LlcpMac_eLinkStatus_t eLinkStatus)754 static void nfc_jni_llcp_linkStatus_callback(void *pContext,
755                                                     phFriNfc_LlcpMac_eLinkStatus_t   eLinkStatus)
756 {
757    phFriNfc_Llcp_sLinkParameters_t  sLinkParams;
758    JNIEnv *e;
759    NFCSTATUS status;
760 
761    struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
762 
763    struct nfc_jni_native_data *nat = (nfc_jni_native_data *)pContextData->pContext;
764 
765    nfc_jni_listen_data_t * pListenData = NULL;
766    nfc_jni_native_monitor * pMonitor = nfc_jni_get_monitor();
767 
768    TRACE("Callback: nfc_jni_llcp_linkStatus_callback()");
769 
770    nat->vm->GetEnv( (void **)&e, nat->env_version);
771 
772    /* Update link status */
773    g_eLinkStatus = eLinkStatus;
774 
775    if(eLinkStatus == phFriNfc_LlcpMac_eLinkActivated)
776    {
777       REENTRANCE_LOCK();
778       status = phLibNfc_Llcp_GetRemoteInfo(hLlcpHandle, &sLinkParams);
779       REENTRANCE_UNLOCK();
780       if(status != NFCSTATUS_SUCCESS)
781       {
782            ALOGW("GetRemote Info failded - Status = %02x",status);
783       }
784       else
785       {
786            ALOGI("LLCP Link activated (LTO=%d, MIU=%d, OPTION=0x%02x, WKS=0x%02x)",sLinkParams.lto,
787                                                                                   sLinkParams.miu,
788                                                                                   sLinkParams.option,
789                                                                                   sLinkParams.wks);
790            device_connected_flag = 1;
791       }
792    }
793    else if(eLinkStatus == phFriNfc_LlcpMac_eLinkDeactivated)
794    {
795       ALOGI("LLCP Link deactivated");
796       free(pContextData);
797       /* Reset device connected flag */
798       device_connected_flag = 0;
799 
800       /* Reset incoming socket list */
801       while (!LIST_EMPTY(&pMonitor->incoming_socket_head))
802       {
803          pListenData = LIST_FIRST(&pMonitor->incoming_socket_head);
804          LIST_REMOVE(pListenData, entries);
805          free(pListenData);
806       }
807 
808       /* Notify manager that the LLCP is lost or deactivated */
809       e->CallVoidMethod(nat->manager, cached_NfcManager_notifyLlcpLinkDeactivated, nat->tag);
810       if(e->ExceptionCheck())
811       {
812          ALOGE("Exception occured");
813          kill_client(nat);
814       }
815    }
816 }
817 
nfc_jni_checkLlcp_callback(void * context,NFCSTATUS status)818 static void nfc_jni_checkLlcp_callback(void *context,
819                                               NFCSTATUS status)
820 {
821    struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)context;
822 
823    LOG_CALLBACK("nfc_jni_checkLlcp_callback", status);
824 
825    pContextData->status = status;
826    sem_post(&pContextData->sem);
827 }
828 
nfc_jni_llcpcfg_callback(void * pContext,NFCSTATUS status)829 static void nfc_jni_llcpcfg_callback(void *pContext, NFCSTATUS status)
830 {
831    struct nfc_jni_callback_data * pCallbackData = (struct nfc_jni_callback_data *) pContext;
832    LOG_CALLBACK("nfc_jni_llcpcfg_callback", status);
833 
834    /* Report the callback status and wake up the caller */
835    pCallbackData->status = status;
836    sem_post(&pCallbackData->sem);
837 }
838 
nfc_jni_llcp_transport_listen_socket_callback(void * pContext,phLibNfc_Handle hIncomingSocket)839 static void nfc_jni_llcp_transport_listen_socket_callback(void              *pContext,
840                                                           phLibNfc_Handle   hIncomingSocket)
841 {
842    phLibNfc_Handle hServiceSocket = (phLibNfc_Handle)pContext;
843    nfc_jni_listen_data_t * pListenData = NULL;
844    nfc_jni_native_monitor * pMonitor = nfc_jni_get_monitor();
845 
846    TRACE("nfc_jni_llcp_transport_listen_socket_callback socket handle = %p", (void*)hIncomingSocket);
847 
848    pthread_mutex_lock(&pMonitor->incoming_socket_mutex);
849 
850    /* Store the connection request */
851    pListenData = (nfc_jni_listen_data_t*)malloc(sizeof(nfc_jni_listen_data_t));
852    if (pListenData == NULL)
853    {
854       ALOGE("Failed to create structure to handle incoming LLCP connection request");
855       goto clean_and_return;
856    }
857    pListenData->pServerSocket = hServiceSocket;
858    pListenData->pIncomingSocket = hIncomingSocket;
859    LIST_INSERT_HEAD(&pMonitor->incoming_socket_head, pListenData, entries);
860 
861    /* Signal pending accept operations that the list is updated */
862    pthread_cond_broadcast(&pMonitor->incoming_socket_cond);
863 
864 clean_and_return:
865    pthread_mutex_unlock(&pMonitor->incoming_socket_mutex);
866 }
867 
nfc_jni_llcp_transport_socket_err_callback(void * pContext,uint8_t nErrCode)868 void nfc_jni_llcp_transport_socket_err_callback(void*      pContext,
869                                                        uint8_t    nErrCode)
870 {
871    PHNFC_UNUSED_VARIABLE(pContext);
872 
873    TRACE("Callback: nfc_jni_llcp_transport_socket_err_callback()");
874 
875    if(nErrCode == PHFRINFC_LLCP_ERR_FRAME_REJECTED)
876    {
877       ALOGW("Frame Rejected - Disconnected");
878    }
879    else if(nErrCode == PHFRINFC_LLCP_ERR_DISCONNECTED)
880    {
881       ALOGD("Socket Disconnected");
882    }
883 }
884 
885 
nfc_jni_discover_callback(void * pContext,NFCSTATUS status)886 static void nfc_jni_discover_callback(void *pContext, NFCSTATUS status)
887 {
888     struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
889 
890     LOG_CALLBACK("nfc_jni_discover_callback", status);
891 
892     pContextData->status = status;
893     sem_post(&pContextData->sem);
894 }
895 
find_preferred_target(phLibNfc_RemoteDevList_t * psRemoteDevList,uint8_t uNoOfRemoteDev)896 static uint8_t find_preferred_target(phLibNfc_RemoteDevList_t *psRemoteDevList,
897         uint8_t uNoOfRemoteDev)
898 {
899     // Always prefer p2p targets over other targets. Otherwise, select the first target
900     // reported.
901     uint8_t preferred_index = 0;
902     for (uint8_t i = 0; i < uNoOfRemoteDev; i++) {
903         if((psRemoteDevList[i].psRemoteDevInfo->RemDevType == phNfc_eNfcIP1_Initiator)
904                 || (psRemoteDevList[i].psRemoteDevInfo->RemDevType == phNfc_eNfcIP1_Target)) {
905             preferred_index = i;
906         }
907     }
908     return preferred_index;
909 }
910 
nfc_jni_Discovery_notification_callback(void * pContext,phLibNfc_RemoteDevList_t * psRemoteDevList,uint8_t uNofRemoteDev,NFCSTATUS status)911 static void nfc_jni_Discovery_notification_callback(void *pContext,
912    phLibNfc_RemoteDevList_t *psRemoteDevList,
913    uint8_t uNofRemoteDev, NFCSTATUS status)
914 {
915    NFCSTATUS ret;
916    const char * typeName;
917    struct timespec ts;
918    phNfc_sData_t data;
919    int i;
920    int target_index = 0; // Target that will be reported (if multiple can be >0)
921 
922    struct nfc_jni_native_data* nat = (struct nfc_jni_native_data *)pContext;
923 
924    JNIEnv *e;
925    nat->vm->GetEnv( (void **)&e, nat->env_version);
926 
927    if(status == NFCSTATUS_DESELECTED)
928    {
929       LOG_CALLBACK("nfc_jni_Discovery_notification_callback: Target deselected", status);
930 
931       /* Notify manager that a target was deselected */
932       e->CallVoidMethod(nat->manager, cached_NfcManager_notifyTargetDeselected);
933       if(e->ExceptionCheck())
934       {
935          ALOGE("Exception occurred");
936          kill_client(nat);
937       }
938    }
939    else
940    {
941       LOG_CALLBACK("nfc_jni_Discovery_notification_callback", status);
942       TRACE("Discovered %d tags", uNofRemoteDev);
943 
944       target_index = find_preferred_target(psRemoteDevList, uNofRemoteDev);
945 
946       ScopedLocalRef<jobject> tag(e, NULL);
947 
948       /* Reset device connected flag */
949       device_connected_flag = 1;
950       phLibNfc_sRemoteDevInformation_t *remDevInfo = psRemoteDevList[target_index].psRemoteDevInfo;
951       phLibNfc_Handle remDevHandle = psRemoteDevList[target_index].hTargetDev;
952       if((remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator)
953           || (remDevInfo->RemDevType == phNfc_eNfcIP1_Target))
954       {
955          ScopedLocalRef<jclass> tag_cls(e, e->GetObjectClass(nat->cached_P2pDevice));
956          if(e->ExceptionCheck())
957          {
958             ALOGE("Get Object Class Error");
959             kill_client(nat);
960             return;
961          }
962 
963          /* New target instance */
964          jmethodID ctor = e->GetMethodID(tag_cls.get(), "<init>", "()V");
965          tag.reset(e->NewObject(tag_cls.get(), ctor));
966 
967          /* Set P2P Target mode */
968          jfieldID f = e->GetFieldID(tag_cls.get(), "mMode", "I");
969 
970          if(remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator)
971          {
972             ALOGD("Discovered P2P Initiator");
973             e->SetIntField(tag.get(), f, (jint)MODE_P2P_INITIATOR);
974          }
975          else
976          {
977             ALOGD("Discovered P2P Target");
978             e->SetIntField(tag.get(), f, (jint)MODE_P2P_TARGET);
979          }
980 
981          if(remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator)
982          {
983             /* Set General Bytes */
984             f = e->GetFieldID(tag_cls.get(), "mGeneralBytes", "[B");
985 
986            TRACE("General Bytes length =");
987            for(i=0;i<remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length;i++)
988            {
989                ALOGD("%02x ", remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo[i]);
990            }
991 
992             ScopedLocalRef<jbyteArray> generalBytes(e, e->NewByteArray(remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length));
993 
994             e->SetByteArrayRegion(generalBytes.get(), 0,
995                                   remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length,
996                                   (jbyte *)remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo);
997             e->SetObjectField(tag.get(), f, generalBytes.get());
998          }
999 
1000          /* Set tag handle */
1001          f = e->GetFieldID(tag_cls.get(), "mHandle", "I");
1002          e->SetIntField(tag.get(), f,(jint)remDevHandle);
1003          TRACE("Target handle = 0x%08x",remDevHandle);
1004       }
1005       else
1006       {
1007         ScopedLocalRef<jclass> tag_cls(e, e->GetObjectClass(nat->cached_NfcTag));
1008         if(e->ExceptionCheck())
1009         {
1010             kill_client(nat);
1011             return;
1012         }
1013 
1014         /* New tag instance */
1015         jmethodID ctor = e->GetMethodID(tag_cls.get(), "<init>", "()V");
1016         tag.reset(e->NewObject(tag_cls.get(), ctor));
1017 
1018         bool multi_protocol = false;
1019 
1020         if(status == NFCSTATUS_MULTIPLE_PROTOCOLS)
1021         {
1022             TRACE("Multiple Protocol TAG detected\n");
1023             multi_protocol = true;
1024         }
1025 
1026         /* Set tag UID */
1027         jfieldID f = e->GetFieldID(tag_cls.get(), "mUid", "[B");
1028         data = get_target_uid(remDevInfo);
1029         ScopedLocalRef<jbyteArray> tagUid(e, e->NewByteArray(data.length));
1030         if(data.length > 0)
1031         {
1032            e->SetByteArrayRegion(tagUid.get(), 0, data.length, (jbyte *)data.buffer);
1033         }
1034         e->SetObjectField(tag.get(), f, tagUid.get());
1035 
1036         /* Generate technology list */
1037         ScopedLocalRef<jintArray> techList(e, NULL);
1038         ScopedLocalRef<jintArray> handleList(e, NULL);
1039         ScopedLocalRef<jintArray> typeList(e, NULL);
1040         nfc_jni_get_technology_tree(e, psRemoteDevList,
1041                 multi_protocol ? uNofRemoteDev : 1,
1042                 &techList, &handleList, &typeList);
1043 
1044         /* Push the technology list into the java object */
1045         f = e->GetFieldID(tag_cls.get(), "mTechList", "[I");
1046         e->SetObjectField(tag.get(), f, techList.get());
1047 
1048         f = e->GetFieldID(tag_cls.get(), "mTechHandles", "[I");
1049         e->SetObjectField(tag.get(), f, handleList.get());
1050 
1051         f = e->GetFieldID(tag_cls.get(), "mTechLibNfcTypes", "[I");
1052         e->SetObjectField(tag.get(), f, typeList.get());
1053 
1054         f = e->GetFieldID(tag_cls.get(), "mConnectedTechIndex", "I");
1055         e->SetIntField(tag.get(), f,(jint)-1);
1056 
1057         f = e->GetFieldID(tag_cls.get(), "mConnectedHandle", "I");
1058         e->SetIntField(tag.get(), f,(jint)-1);
1059 
1060         set_target_pollBytes(e, tag.get(), psRemoteDevList->psRemoteDevInfo);
1061 
1062         set_target_activationBytes(e, tag.get(), psRemoteDevList->psRemoteDevInfo);
1063       }
1064 
1065       storedHandle = remDevHandle;
1066       if (nat->tag != NULL) {
1067           e->DeleteGlobalRef(nat->tag);
1068       }
1069       nat->tag = e->NewGlobalRef(tag.get());
1070 
1071       /* Notify the service */
1072       TRACE("Notify Nfc Service");
1073       if((remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator)
1074           || (remDevInfo->RemDevType == phNfc_eNfcIP1_Target))
1075       {
1076          /* Store the handle of the P2P device */
1077          hLlcpHandle = remDevHandle;
1078 
1079          /* Notify manager that new a P2P device was found */
1080          e->CallVoidMethod(nat->manager, cached_NfcManager_notifyLlcpLinkActivation, tag.get());
1081          if(e->ExceptionCheck())
1082          {
1083             ALOGE("Exception occurred");
1084             kill_client(nat);
1085          }
1086       }
1087       else
1088       {
1089          /* Notify manager that new a tag was found */
1090          e->CallVoidMethod(nat->manager, cached_NfcManager_notifyNdefMessageListeners, tag.get());
1091          if(e->ExceptionCheck())
1092          {
1093             ALOGE("Exception occurred");
1094             kill_client(nat);
1095          }
1096       }
1097    }
1098 }
1099 
nfc_jni_init_callback(void * pContext,NFCSTATUS status)1100 static void nfc_jni_init_callback(void *pContext, NFCSTATUS status)
1101 {
1102    struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
1103 
1104    LOG_CALLBACK("nfc_jni_init_callback", status);
1105 
1106    pContextData->status = status;
1107    sem_post(&pContextData->sem);
1108 }
1109 
nfc_jni_deinit_callback(void * pContext,NFCSTATUS status)1110 static void nfc_jni_deinit_callback(void *pContext, NFCSTATUS status)
1111 {
1112    struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
1113 
1114    LOG_CALLBACK("nfc_jni_deinit_callback", status);
1115 
1116    pContextData->status = status;
1117    sem_post(&pContextData->sem);
1118 }
1119 
1120 /* Set Secure Element mode callback*/
nfc_jni_smartMX_setModeCb(void * pContext,phLibNfc_Handle hSecureElement,NFCSTATUS status)1121 static void nfc_jni_smartMX_setModeCb (void*            pContext,
1122                                        phLibNfc_Handle  hSecureElement,
1123                                        NFCSTATUS        status)
1124 {
1125    struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
1126 
1127    LOG_CALLBACK("nfc_jni_smartMX_setModeCb", status);
1128 
1129    pContextData->status = status;
1130    sem_post(&pContextData->sem);
1131 }
1132 
1133 /* Card Emulation callback */
nfc_jni_transaction_callback(void * context,phLibNfc_eSE_EvtType_t evt_type,phLibNfc_Handle handle,phLibNfc_uSeEvtInfo_t * evt_info,NFCSTATUS status)1134 static void nfc_jni_transaction_callback(void *context,
1135    phLibNfc_eSE_EvtType_t evt_type, phLibNfc_Handle handle,
1136    phLibNfc_uSeEvtInfo_t *evt_info, NFCSTATUS status)
1137 {
1138     JNIEnv *e;
1139     jobject tmp_array = NULL;
1140     jobject mifare_block = NULL;
1141     struct nfc_jni_native_data *nat;
1142     phNfc_sData_t *aid;
1143     phNfc_sData_t *mifare_command;
1144     struct nfc_jni_callback_data *pCallbackData;
1145     int i=0;
1146 
1147     LOG_CALLBACK("nfc_jni_transaction_callback", status);
1148 
1149     nat = (struct nfc_jni_native_data *)context;
1150 
1151     nat->vm->GetEnv( (void **)&e, nat->env_version);
1152 
1153     if(status == NFCSTATUS_SUCCESS)
1154     {
1155         switch(evt_type)
1156         {
1157             case phLibNfc_eSE_EvtStartTransaction:
1158             {
1159                 TRACE("> SE EVT_START_TRANSACTION");
1160                 if(evt_info->UiccEvtInfo.aid.length <= AID_MAXLEN)
1161                 {
1162                     aid = &(evt_info->UiccEvtInfo.aid);
1163 
1164                     ALOGD("> AID DETECTED");
1165 
1166                     if(aid != NULL)
1167                     {
1168                         if (TRACE_ENABLED == 1) {
1169                             char aid_str[AID_MAXLEN * 2 + 1];
1170                             aid_str[0] = '\0';
1171                             for (i = 0; i < (int) (aid->length) && i < AID_MAXLEN; i++) {
1172                               snprintf(&aid_str[i*2], 3, "%02x", aid->buffer[i]);
1173                             }
1174                             ALOGD("> AID: %s", aid_str);
1175                         }
1176                         tmp_array = e->NewByteArray(aid->length);
1177                         if (tmp_array == NULL)
1178                         {
1179                             goto error;
1180                         }
1181 
1182                         e->SetByteArrayRegion((jbyteArray)tmp_array, 0, aid->length, (jbyte *)aid->buffer);
1183                         if(e->ExceptionCheck())
1184                         {
1185                             goto error;
1186                         }
1187                     }
1188                     else
1189                     {
1190                         goto error;
1191                     }
1192 
1193                     TRACE("Notify Nfc Service");
1194                     /* Notify manager that a new event occurred on a SE */
1195                     e->CallVoidMethod(nat->manager, cached_NfcManager_notifyTransactionListeners, tmp_array);
1196                     if(e->ExceptionCheck())
1197                     {
1198                         goto error;
1199                     }
1200                 }
1201                 else
1202                 {
1203                     ALOGD("> NO AID DETECTED");
1204                 }
1205             }break;
1206 
1207             case phLibNfc_eSE_EvtApduReceived:
1208             {
1209                 phNfc_sData_t *apdu = &(evt_info->UiccEvtInfo.aid);
1210                 TRACE("> SE EVT_APDU_RECEIVED");
1211 
1212                 if (apdu != NULL) {
1213                         TRACE("  APDU length=%d", apdu->length);
1214                         tmp_array = e->NewByteArray(apdu->length);
1215                         if (tmp_array == NULL) {
1216                             goto error;
1217                         }
1218                         e->SetByteArrayRegion((jbyteArray)tmp_array, 0, apdu->length, (jbyte *)apdu->buffer);
1219                         if (e->ExceptionCheck()) {
1220                             goto error;
1221                         }
1222                 } else {
1223                         TRACE("  APDU EMPTY");
1224                 }
1225 
1226                 TRACE("Notify Nfc Service");
1227                 e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeApduReceived, tmp_array);
1228             }break;
1229 
1230             case phLibNfc_eSE_EvtCardRemoval:
1231             {
1232                 TRACE("> SE EVT_EMV_CARD_REMOVAL");
1233                 TRACE("Notify Nfc Service");
1234                 e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeEmvCardRemoval);
1235             }break;
1236 
1237             case phLibNfc_eSE_EvtMifareAccess:
1238             {
1239                 TRACE("> SE EVT_MIFARE_ACCESS");
1240                 mifare_command = &(evt_info->UiccEvtInfo.aid);
1241                 TRACE("> MIFARE Block: %d",mifare_command->buffer[1]);
1242                 tmp_array = e->NewByteArray(2);
1243                 if (tmp_array == NULL)
1244                 {
1245                     goto error;
1246                 }
1247 
1248                 e->SetByteArrayRegion((jbyteArray)tmp_array, 0, 2, (jbyte *)mifare_command->buffer);
1249                 if(e->ExceptionCheck())
1250                 {
1251                     goto error;
1252                 }
1253                 TRACE("Notify Nfc Service");
1254                 e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeMifareAccess, mifare_block);
1255             }break;
1256 
1257             case phLibNfc_eSE_EvtFieldOn:
1258             {
1259                 TRACE("> SE EVT_FIELD_ON");
1260                 TRACE("Notify Nfc Service");
1261                 e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeFieldActivated);
1262             }break;
1263 
1264             case phLibNfc_eSE_EvtFieldOff:
1265             {
1266                 TRACE("> SE EVT_FIELD_OFF");
1267                 TRACE("Notify Nfc Service");
1268                 e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeFieldDeactivated);
1269             }break;
1270 
1271             default:
1272             {
1273                 TRACE("Unknown SE event");
1274             }break;
1275         }
1276     }
1277     else
1278     {
1279         ALOGE("SE transaction notification error");
1280         goto error;
1281     }
1282 
1283     /* Function finished, now clean and return */
1284     goto clean_and_return;
1285 
1286  error:
1287     /* In case of error, just discard the notification */
1288     ALOGE("Failed to send SE transaction notification");
1289     e->ExceptionClear();
1290 
1291  clean_and_return:
1292     if(tmp_array != NULL)
1293     {
1294        e->DeleteLocalRef(tmp_array);
1295     }
1296 }
1297 
nfc_jni_se_set_mode_callback(void * pContext,phLibNfc_Handle handle,NFCSTATUS status)1298 static void nfc_jni_se_set_mode_callback(void *pContext,
1299    phLibNfc_Handle handle, NFCSTATUS status)
1300 {
1301    struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
1302 
1303    LOG_CALLBACK("nfc_jni_se_set_mode_callback", status);
1304 
1305    pContextData->status = status;
1306    sem_post(&pContextData->sem);
1307 }
1308 
1309 /*
1310  * NFCManager methods
1311  */
1312 
nfc_jni_start_discovery_locked(struct nfc_jni_native_data * nat,bool resume)1313 static void nfc_jni_start_discovery_locked(struct nfc_jni_native_data *nat, bool resume)
1314 {
1315    NFCSTATUS ret;
1316    struct nfc_jni_callback_data cb_data;
1317    int numRetries = 3;
1318 
1319    /* Create the local semaphore */
1320    if (!nfc_cb_data_init(&cb_data, NULL))
1321    {
1322       goto clean_and_return;
1323    }
1324    /* Reset the PN544 ISO XCHG / sw watchdog timeouts */
1325    nfc_jni_reset_timeout_values();
1326 
1327    /* Reload the p2p modes */
1328    nat->discovery_cfg.NfcIP_Mode = nat->p2p_initiator_modes;  //initiator
1329    nat->discovery_cfg.NfcIP_Target_Mode = nat->p2p_target_modes;  //target
1330    nat->discovery_cfg.NfcIP_Tgt_Disable = FALSE;
1331 
1332    /* Reset device connected flag */
1333    device_connected_flag = 0;
1334 configure:
1335    /* Start Polling loop */
1336    TRACE("******  Start NFC Discovery ******");
1337    REENTRANCE_LOCK();
1338    ret = phLibNfc_Mgt_ConfigureDiscovery(resume ? NFC_DISCOVERY_RESUME : NFC_DISCOVERY_CONFIG,
1339       nat->discovery_cfg, nfc_jni_discover_callback, (void *)&cb_data);
1340    REENTRANCE_UNLOCK();
1341    TRACE("phLibNfc_Mgt_ConfigureDiscovery(%s-%s-%s-%s-%s-%s, %s-%x-%x) returned 0x%08x\n",
1342       nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A==TRUE?"3A":"",
1343       nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B==TRUE?"3B":"",
1344       nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212==TRUE?"F2":"",
1345       nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424==TRUE?"F4":"",
1346       nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive==TRUE?"NFC":"",
1347       nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693==TRUE?"RFID":"",
1348       nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation==FALSE?"CE":"",
1349       nat->discovery_cfg.NfcIP_Mode, nat->discovery_cfg.Duration, ret);
1350 
1351    if (ret == NFCSTATUS_BUSY && numRetries-- > 0)
1352    {
1353       TRACE("ConfigDiscovery BUSY, retrying");
1354       usleep(1000000);
1355       goto configure;
1356    }
1357 
1358    if(ret != NFCSTATUS_PENDING)
1359    {
1360       emergency_recovery(nat);
1361       goto clean_and_return;
1362    }
1363 
1364    /* Wait for callback response */
1365    if(sem_wait(&cb_data.sem))
1366    {
1367       ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
1368       goto clean_and_return;
1369    }
1370 
1371 clean_and_return:
1372    nfc_cb_data_deinit(&cb_data);
1373 }
1374 
nfc_jni_stop_discovery_locked(struct nfc_jni_native_data * nat)1375 static void nfc_jni_stop_discovery_locked(struct nfc_jni_native_data *nat)
1376 {
1377    phLibNfc_sADD_Cfg_t discovery_cfg;
1378    NFCSTATUS ret;
1379    struct nfc_jni_callback_data cb_data;
1380    int numRetries = 3;
1381 
1382    /* Create the local semaphore */
1383    if (!nfc_cb_data_init(&cb_data, NULL))
1384    {
1385       goto clean_and_return;
1386    }
1387 
1388    discovery_cfg.PollDevInfo.PollEnabled = 0;
1389    discovery_cfg.NfcIP_Mode = phNfc_eDefaultP2PMode;
1390    discovery_cfg.NfcIP_Target_Mode = 0;
1391    discovery_cfg.NfcIP_Tgt_Disable = TRUE;
1392 
1393 configure:
1394    /* Start Polling loop */
1395    TRACE("******  Stop NFC Discovery ******");
1396    REENTRANCE_LOCK();
1397    ret = phLibNfc_Mgt_ConfigureDiscovery(NFC_DISCOVERY_CONFIG,discovery_cfg, nfc_jni_discover_callback, (void *)&cb_data);
1398    REENTRANCE_UNLOCK();
1399    TRACE("phLibNfc_Mgt_ConfigureDiscovery(%s-%s-%s-%s-%s-%s, %s-%x-%x) returned 0x%08x\n",
1400       discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A==TRUE?"3A":"",
1401       discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B==TRUE?"3B":"",
1402       discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212==TRUE?"F2":"",
1403       discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424==TRUE?"F4":"",
1404       discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive==TRUE?"NFC":"",
1405       discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693==TRUE?"RFID":"",
1406       discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation==FALSE?"CE":"",
1407       discovery_cfg.NfcIP_Mode, discovery_cfg.Duration, ret);
1408 
1409    if (ret == NFCSTATUS_BUSY && numRetries-- > 0)
1410    {
1411       TRACE("ConfigDiscovery BUSY, retrying");
1412       usleep(1000000);
1413       goto configure;
1414    }
1415 
1416    if(ret != NFCSTATUS_PENDING)
1417    {
1418       ALOGE("[STOP] ConfigDiscovery returned %x", ret);
1419       emergency_recovery(nat);
1420    }
1421 
1422    /* Wait for callback response */
1423    if(sem_wait(&cb_data.sem))
1424    {
1425       ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
1426       goto clean_and_return;
1427    }
1428 
1429 clean_and_return:
1430    nfc_cb_data_deinit(&cb_data);
1431 }
1432 
1433 
com_android_nfc_NfcManager_disableDiscovery(JNIEnv * e,jobject o)1434 static void com_android_nfc_NfcManager_disableDiscovery(JNIEnv *e, jobject o)
1435 {
1436     struct nfc_jni_native_data *nat;
1437 
1438     CONCURRENCY_LOCK();
1439 
1440     /* Retrieve native structure address */
1441     nat = nfc_jni_get_nat(e, o);
1442 
1443     nfc_jni_stop_discovery_locked(nat);
1444 
1445     CONCURRENCY_UNLOCK();
1446 
1447 }
1448 
com_android_nfc_NfcManager_enableDiscovery(JNIEnv * e,jobject o)1449 static void com_android_nfc_NfcManager_enableDiscovery(JNIEnv *e, jobject o) {
1450     NFCSTATUS ret;
1451     struct nfc_jni_native_data *nat;
1452 
1453     CONCURRENCY_LOCK();
1454 
1455     nat = nfc_jni_get_nat(e, o);
1456 
1457    /* Register callback for remote device notifications.
1458     * Must re-register every time we turn on discovery, since other operations
1459     * (such as opening the Secure Element) can change the remote device
1460     * notification callback*/
1461    REENTRANCE_LOCK();
1462    ret = phLibNfc_RemoteDev_NtfRegister(&nat->registry_info, nfc_jni_Discovery_notification_callback, (void *)nat);
1463    REENTRANCE_UNLOCK();
1464    if(ret != NFCSTATUS_SUCCESS)
1465    {
1466         ALOGD("pphLibNfc_RemoteDev_NtfRegister returned 0x%02x",ret);
1467         goto clean_and_return;
1468    }
1469    TRACE("phLibNfc_RemoteDev_NtfRegister(%s-%s-%s-%s-%s-%s-%s-%s) returned 0x%x\n",
1470       nat->registry_info.Jewel==TRUE?"J":"",
1471       nat->registry_info.MifareUL==TRUE?"UL":"",
1472       nat->registry_info.MifareStd==TRUE?"Mi":"",
1473       nat->registry_info.Felica==TRUE?"F":"",
1474       nat->registry_info.ISO14443_4A==TRUE?"4A":"",
1475       nat->registry_info.ISO14443_4B==TRUE?"4B":"",
1476       nat->registry_info.NFC==TRUE?"P2P":"",
1477       nat->registry_info.ISO15693==TRUE?"R":"", ret);
1478 
1479     nfc_jni_start_discovery_locked(nat, false);
1480 clean_and_return:
1481     CONCURRENCY_UNLOCK();
1482 }
1483 
com_android_nfc_NfcManager_doResetTimeouts(JNIEnv * e,jobject o)1484 static void com_android_nfc_NfcManager_doResetTimeouts( JNIEnv *e, jobject o) {
1485     CONCURRENCY_LOCK();
1486     nfc_jni_reset_timeout_values();
1487     CONCURRENCY_UNLOCK();
1488 }
1489 
setFelicaTimeout(jint timeout)1490 static void setFelicaTimeout(jint timeout) {
1491    // The Felica timeout is configurable in the PN544 upto a maximum of 255 ms.
1492    // It can be set to 0 to disable the timeout altogether, in which case we
1493    // use the sw watchdog as a fallback.
1494    if (timeout <= 255) {
1495        phLibNfc_SetFelicaTimeout(timeout);
1496    } else {
1497        // Disable hw timeout, use sw watchdog for timeout
1498        phLibNfc_SetFelicaTimeout(0);
1499        phLibNfc_SetHciTimeout(timeout);
1500    }
1501 
1502 }
1503 // Calculates ceiling log2 of value
log2(int value)1504 static unsigned int log2(int value) {
1505     unsigned int ret = 0;
1506     bool isPowerOf2 = ((value & (value - 1)) == 0);
1507     while ( (value >> ret) > 1 ) ret++;
1508     if (!isPowerOf2) ret++;
1509     return ret;
1510 }
1511 
1512 // The Iso/Mifare Xchg timeout in PN544 is a non-linear function over X
1513 // spanning 0 - 4.9s: timeout in seconds = (256 * 16 / 13560000) * 2 ^ X
1514 //
1515 // We keep the constant part of the formula in a static; note the factor
1516 // 1000 off, which is due to the fact that the formula calculates seconds,
1517 // but this method gets milliseconds as an argument.
1518 static double nxp_nfc_timeout_factor = (256 * 16) / 13560.0;
1519 
calcTimeout(int timeout_in_ms)1520 static int calcTimeout(int timeout_in_ms) {
1521    // timeout = (256 * 16 / 13560000) * 2 ^ X
1522    // First find the first X for which timeout > requested timeout
1523    return (log2(ceil(((double) timeout_in_ms) / nxp_nfc_timeout_factor)));
1524 }
1525 
setIsoDepTimeout(jint timeout)1526 static void setIsoDepTimeout(jint timeout) {
1527    if (timeout <= 4900) {
1528        int value = calcTimeout(timeout);
1529        // Then re-compute the actual timeout based on X
1530        double actual_timeout = nxp_nfc_timeout_factor * (1 << value);
1531        // Set the sw watchdog a bit longer (The PN544 timeout is very accurate,
1532        // but it will take some time to get back through the sw layers.
1533        // 500 ms should be enough).
1534        phLibNfc_SetHciTimeout(ceil(actual_timeout + 500));
1535        value |= 0x10; // bit 4 to enable timeout
1536        phLibNfc_SetIsoXchgTimeout(value);
1537    }
1538    else {
1539        // Also note that if we desire a timeout > 4.9s, the Iso Xchg timeout
1540        // must be disabled completely, to prevent the PN544 from aborting
1541        // the transaction. We reuse the HCI sw watchdog to catch the timeout
1542        // in that case.
1543        phLibNfc_SetIsoXchgTimeout(0x00);
1544        phLibNfc_SetHciTimeout(timeout);
1545    }
1546 }
1547 
setNfcATimeout(jint timeout)1548 static void setNfcATimeout(jint timeout) {
1549    if (timeout <= 4900) {
1550        int value = calcTimeout(timeout);
1551        phLibNfc_SetMifareRawTimeout(value);
1552    }
1553    else {
1554        // Disable mifare raw timeout, use HCI sw watchdog instead
1555        phLibNfc_SetMifareRawTimeout(0x00);
1556        phLibNfc_SetHciTimeout(timeout);
1557    }
1558 }
1559 
com_android_nfc_NfcManager_doSetTimeout(JNIEnv * e,jobject o,jint tech,jint timeout)1560 static bool com_android_nfc_NfcManager_doSetTimeout( JNIEnv *e, jobject o,
1561         jint tech, jint timeout) {
1562     bool success = false;
1563     CONCURRENCY_LOCK();
1564     if (timeout <= 0) {
1565         ALOGE("Timeout must be positive.");
1566         return false;
1567     } else {
1568         switch (tech) {
1569             case TARGET_TYPE_MIFARE_CLASSIC:
1570             case TARGET_TYPE_MIFARE_UL:
1571                 // Intentional fall-through, Mifare UL, Classic
1572                 // transceive just uses raw 3A frames
1573             case TARGET_TYPE_ISO14443_3A:
1574                 setNfcATimeout(timeout);
1575                 success = true;
1576                 break;
1577             case TARGET_TYPE_ISO14443_4:
1578                 setIsoDepTimeout(timeout);
1579                 success = true;
1580                 break;
1581             case TARGET_TYPE_FELICA:
1582                 setFelicaTimeout(timeout);
1583                 success = true;
1584                 break;
1585             default:
1586                 ALOGW("doSetTimeout: Timeout not supported for tech %d", tech);
1587                 success = false;
1588         }
1589     }
1590     CONCURRENCY_UNLOCK();
1591     return success;
1592 }
1593 
com_android_nfc_NfcManager_doGetTimeout(JNIEnv * e,jobject o,jint tech)1594 static jint com_android_nfc_NfcManager_doGetTimeout( JNIEnv *e, jobject o,
1595         jint tech) {
1596     int timeout = -1;
1597     CONCURRENCY_LOCK();
1598     switch (tech) {
1599         case TARGET_TYPE_MIFARE_CLASSIC:
1600         case TARGET_TYPE_MIFARE_UL:
1601             // Intentional fall-through, Mifare UL, Classic
1602             // transceive just uses raw 3A frames
1603         case TARGET_TYPE_ISO14443_3A:
1604             timeout = phLibNfc_GetMifareRawTimeout();
1605             if (timeout == 0) {
1606                 timeout = phLibNfc_GetHciTimeout();
1607             } else {
1608                 // Timeout returned from libnfc needs conversion to ms
1609                 timeout = (nxp_nfc_timeout_factor * (1 << timeout));
1610             }
1611             break;
1612         case TARGET_TYPE_ISO14443_4:
1613             timeout = phLibNfc_GetIsoXchgTimeout() & 0x0F; // lower 4 bits only
1614             if (timeout == 0) {
1615                 timeout = phLibNfc_GetHciTimeout();
1616             } else {
1617                 // Timeout returned from libnfc needs conversion to ms
1618                 timeout = (nxp_nfc_timeout_factor * (1 << timeout));
1619             }
1620             break;
1621         case TARGET_TYPE_FELICA:
1622             timeout = phLibNfc_GetFelicaTimeout();
1623             if (timeout == 0) {
1624                 timeout = phLibNfc_GetHciTimeout();
1625             } else {
1626                 // Felica timeout already in ms
1627             }
1628             break;
1629         default:
1630             ALOGW("doGetTimeout: Timeout not supported for tech %d", tech);
1631             break;
1632     }
1633     CONCURRENCY_UNLOCK();
1634     return timeout;
1635 }
1636 
1637 
com_android_nfc_NfcManager_init_native_struc(JNIEnv * e,jobject o)1638 static jboolean com_android_nfc_NfcManager_init_native_struc(JNIEnv *e, jobject o)
1639 {
1640    NFCSTATUS status;
1641    struct nfc_jni_native_data *nat = NULL;
1642    jclass cls;
1643    jobject obj;
1644    jfieldID f;
1645 
1646    TRACE("******  Init Native Structure ******");
1647 
1648    /* Initialize native structure */
1649    nat = (nfc_jni_native_data*)malloc(sizeof(struct nfc_jni_native_data));
1650    if(nat == NULL)
1651    {
1652       ALOGD("malloc of nfc_jni_native_data failed");
1653       return FALSE;
1654    }
1655    memset(nat, 0, sizeof(*nat));
1656    e->GetJavaVM(&(nat->vm));
1657    nat->env_version = e->GetVersion();
1658    nat->manager = e->NewGlobalRef(o);
1659 
1660    cls = e->GetObjectClass(o);
1661    f = e->GetFieldID(cls, "mNative", "I");
1662    e->SetIntField(o, f, (jint)nat);
1663 
1664    /* Initialize native cached references */
1665    cached_NfcManager_notifyNdefMessageListeners = e->GetMethodID(cls,
1666       "notifyNdefMessageListeners","(Lcom/android/nfc/dhimpl/NativeNfcTag;)V");
1667 
1668    cached_NfcManager_notifyTransactionListeners = e->GetMethodID(cls,
1669       "notifyTransactionListeners", "([B)V");
1670 
1671    cached_NfcManager_notifyLlcpLinkActivation = e->GetMethodID(cls,
1672       "notifyLlcpLinkActivation","(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V");
1673 
1674    cached_NfcManager_notifyLlcpLinkDeactivated = e->GetMethodID(cls,
1675       "notifyLlcpLinkDeactivated","(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V");
1676 
1677    cached_NfcManager_notifyTargetDeselected = e->GetMethodID(cls,
1678       "notifyTargetDeselected","()V");
1679 
1680    cached_NfcManager_notifySeFieldActivated = e->GetMethodID(cls,
1681       "notifySeFieldActivated", "()V");
1682 
1683    cached_NfcManager_notifySeFieldDeactivated = e->GetMethodID(cls,
1684       "notifySeFieldDeactivated", "()V");
1685 
1686    cached_NfcManager_notifySeApduReceived= e->GetMethodID(cls,
1687       "notifySeApduReceived", "([B)V");
1688 
1689    cached_NfcManager_notifySeMifareAccess = e->GetMethodID(cls,
1690       "notifySeMifareAccess", "([B)V");
1691 
1692    cached_NfcManager_notifySeEmvCardRemoval =  e->GetMethodID(cls,
1693       "notifySeEmvCardRemoval", "()V");
1694 
1695    if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeNfcTag",&(nat->cached_NfcTag)) == -1)
1696    {
1697       ALOGD("Native Structure initialization failed");
1698       return FALSE;
1699    }
1700 
1701    if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeP2pDevice",&(nat->cached_P2pDevice)) == -1)
1702    {
1703       ALOGD("Native Structure initialization failed");
1704       return FALSE;
1705    }
1706    TRACE("****** Init Native Structure OK ******");
1707    return TRUE;
1708 
1709 }
1710 
1711 /* Init/Deinit method */
com_android_nfc_NfcManager_initialize(JNIEnv * e,jobject o)1712 static jboolean com_android_nfc_NfcManager_initialize(JNIEnv *e, jobject o)
1713 {
1714    struct nfc_jni_native_data *nat = NULL;
1715    int init_result = JNI_FALSE;
1716 #ifdef TNFC_EMULATOR_ONLY
1717    char value[PROPERTY_VALUE_MAX];
1718 #endif
1719    jboolean result;
1720 
1721    CONCURRENCY_LOCK();
1722 
1723 #ifdef TNFC_EMULATOR_ONLY
1724    if (!property_get("ro.kernel.qemu", value, 0))
1725    {
1726       ALOGE("NFC Initialization failed: not running in an emulator\n");
1727       goto clean_and_return;
1728    }
1729 #endif
1730 
1731    /* Retrieve native structure address */
1732    nat = nfc_jni_get_nat(e, o);
1733 
1734    nat->seId = SMX_SECURE_ELEMENT_ID;
1735 
1736    nat->lto = 150;  // LLCP_LTO
1737    nat->miu = 128; // LLCP_MIU
1738    // WKS indicates well-known services; 1 << sap for each supported SAP.
1739    // We support Link mgmt (SAP 0), SDP (SAP 1) and SNEP (SAP 4)
1740    nat->wks = 0x13;  // LLCP_WKS
1741    nat->opt = 0;  // LLCP_OPT
1742    nat->p2p_initiator_modes = phNfc_eP2P_ALL;
1743    nat->p2p_target_modes = 0x0E; // All passive except 106, active
1744    nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A = TRUE;
1745    nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B = TRUE;
1746    nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212 = TRUE;
1747    nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424 = TRUE;
1748    nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693 = TRUE;
1749    nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive = TRUE;
1750    nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = FALSE;
1751 
1752    nat->registry_info.MifareUL = TRUE;
1753    nat->registry_info.MifareStd = TRUE;
1754    nat->registry_info.ISO14443_4A = TRUE;
1755    nat->registry_info.ISO14443_4B = TRUE;
1756    nat->registry_info.Jewel = TRUE;
1757    nat->registry_info.Felica = TRUE;
1758    nat->registry_info.NFC = TRUE;
1759    nat->registry_info.ISO15693 = TRUE;
1760 
1761    exported_nat = nat;
1762 
1763    /* Perform the initialization */
1764    init_result = nfc_jni_initialize(nat);
1765 
1766 clean_and_return:
1767    CONCURRENCY_UNLOCK();
1768 
1769    /* Convert the result and return */
1770    return (init_result==TRUE)?JNI_TRUE:JNI_FALSE;
1771 }
1772 
com_android_nfc_NfcManager_deinitialize(JNIEnv * e,jobject o)1773 static jboolean com_android_nfc_NfcManager_deinitialize(JNIEnv *e, jobject o)
1774 {
1775    struct timespec ts;
1776    NFCSTATUS status;
1777    int result = JNI_FALSE;
1778    struct nfc_jni_native_data *nat;
1779    int bStackReset = FALSE;
1780    struct nfc_jni_callback_data cb_data;
1781 
1782    CONCURRENCY_LOCK();
1783 
1784    /* Retrieve native structure address */
1785    nat = nfc_jni_get_nat(e, o);
1786 
1787    /* Clear previous configuration */
1788    memset(&nat->discovery_cfg, 0, sizeof(phLibNfc_sADD_Cfg_t));
1789    memset(&nat->registry_info, 0, sizeof(phLibNfc_Registry_Info_t));
1790 
1791    /* Create the local semaphore */
1792    if (nfc_cb_data_init(&cb_data, NULL))
1793    {
1794       TRACE("phLibNfc_Mgt_DeInitialize()");
1795       REENTRANCE_LOCK();
1796       status = phLibNfc_Mgt_DeInitialize(gHWRef, nfc_jni_deinit_callback, (void *)&cb_data);
1797       REENTRANCE_UNLOCK();
1798       if (status == NFCSTATUS_PENDING)
1799       {
1800          TRACE("phLibNfc_Mgt_DeInitialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
1801 
1802          clock_gettime(CLOCK_REALTIME, &ts);
1803          ts.tv_sec += 5;
1804 
1805          /* Wait for callback response */
1806          if(sem_timedwait(&cb_data.sem, &ts) == -1)
1807          {
1808             ALOGW("Operation timed out");
1809             bStackReset = TRUE;
1810          }
1811 
1812          if(cb_data.status != NFCSTATUS_SUCCESS)
1813          {
1814             ALOGE("Failed to deinit the stack");
1815             bStackReset = TRUE;
1816          }
1817       }
1818       else
1819       {
1820          TRACE("phLibNfc_Mgt_DeInitialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
1821          bStackReset = TRUE;
1822       }
1823       nfc_cb_data_deinit(&cb_data);
1824    }
1825    else
1826    {
1827        ALOGE("Failed to create semaphore (errno=0x%08x)", errno);
1828        bStackReset = TRUE;
1829    }
1830 
1831    kill_client(nat);
1832 
1833    if(bStackReset == TRUE)
1834    {
1835       /* Complete deinit. failed, try hard restart of NFC */
1836       ALOGW("Reseting stack...");
1837       emergency_recovery(nat);
1838    }
1839 
1840    result = nfc_jni_unconfigure_driver(nat);
1841 
1842    TRACE("NFC Deinitialized");
1843 
1844    CONCURRENCY_UNLOCK();
1845 
1846    return TRUE;
1847 }
1848 
1849 /* Secure Element methods */
com_android_nfc_NfcManager_doGetSecureElementList(JNIEnv * e,jobject o)1850 static jintArray com_android_nfc_NfcManager_doGetSecureElementList(JNIEnv *e, jobject o) {
1851     NFCSTATUS ret;
1852     phLibNfc_SE_List_t se_list[PHLIBNFC_MAXNO_OF_SE];
1853     uint8_t i, se_count = PHLIBNFC_MAXNO_OF_SE;
1854 
1855     TRACE("******  Get Secure Element List ******");
1856 
1857     TRACE("phLibNfc_SE_GetSecureElementList()");
1858     REENTRANCE_LOCK();
1859     ret = phLibNfc_SE_GetSecureElementList(se_list, &se_count);
1860     REENTRANCE_UNLOCK();
1861     if (ret != NFCSTATUS_SUCCESS) {
1862         ALOGE("phLibNfc_SE_GetSecureElementList() returned 0x%04x[%s]", ret,
1863                 nfc_jni_get_status_name(ret));
1864         return NULL;
1865     }
1866     TRACE("phLibNfc_SE_GetSecureElementList() returned 0x%04x[%s]", ret,
1867             nfc_jni_get_status_name(ret));
1868 
1869     TRACE("Nb SE: %d", se_count);
1870     jintArray result = e->NewIntArray(se_count);
1871     for (i = 0; i < se_count; i++) {
1872         if (se_list[i].eSE_Type == phLibNfc_SE_Type_SmartMX) {
1873             ALOGD("phLibNfc_SE_GetSecureElementList(): SMX detected");
1874             ALOGD("SE ID #%d: 0x%08x", i, se_list[i].hSecureElement);
1875         } else if(se_list[i].eSE_Type == phLibNfc_SE_Type_UICC) {
1876             ALOGD("phLibNfc_SE_GetSecureElementList(): UICC detected");
1877             ALOGD("SE ID #%d: 0x%08x", i, se_list[i].hSecureElement);
1878         }
1879         e->SetIntArrayRegion(result, i, 1, (jint*)&se_list[i].hSecureElement);
1880     }
1881 
1882     return result;
1883 }
1884 
com_android_nfc_NfcManager_doSelectSecureElement(JNIEnv * e,jobject o)1885 static void com_android_nfc_NfcManager_doSelectSecureElement(JNIEnv *e, jobject o) {
1886     NFCSTATUS ret;
1887     struct nfc_jni_native_data *nat;
1888     struct nfc_jni_callback_data cb_data;
1889 
1890     CONCURRENCY_LOCK();
1891 
1892     /* Retrieve native structure address */
1893     nat = nfc_jni_get_nat(e, o);
1894 
1895     /* Create the local semaphore */
1896     if (!nfc_cb_data_init(&cb_data, NULL)) {
1897         goto clean_and_return;
1898     }
1899 
1900     REENTRANCE_LOCK();
1901     ret = phLibNfc_RemoteDev_NtfRegister(&nat->registry_info, nfc_jni_Discovery_notification_callback, (void *)nat);
1902     REENTRANCE_UNLOCK();
1903     if(ret != NFCSTATUS_SUCCESS) {
1904         ALOGD("pphLibNfc_RemoteDev_NtfRegister returned 0x%02x",ret);
1905         goto clean_and_return;
1906     }
1907     TRACE("******  Select Secure Element ******");
1908 
1909     TRACE("phLibNfc_SE_SetMode()");
1910     /* Set SE mode - Virtual */
1911     REENTRANCE_LOCK();
1912     ret = phLibNfc_SE_SetMode(nat->seId, phLibNfc_SE_ActModeVirtualVolatile, nfc_jni_se_set_mode_callback,
1913             (void *)&cb_data);
1914     REENTRANCE_UNLOCK();
1915     if (ret != NFCSTATUS_PENDING) {
1916         ALOGD("phLibNfc_SE_SetMode() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1917         goto clean_and_return;
1918     }
1919     TRACE("phLibNfc_SE_SetMode() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1920 
1921     /* Wait for callback response */
1922     if (sem_wait(&cb_data.sem)) {
1923         ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
1924         goto clean_and_return;
1925     }
1926 
1927     clean_and_return:
1928     nfc_cb_data_deinit(&cb_data);
1929     CONCURRENCY_UNLOCK();
1930 }
1931 
com_android_nfc_NfcManager_doDeselectSecureElement(JNIEnv * e,jobject o)1932 static void com_android_nfc_NfcManager_doDeselectSecureElement(JNIEnv *e, jobject o) {
1933     NFCSTATUS ret;
1934     struct nfc_jni_native_data *nat;
1935     struct nfc_jni_callback_data cb_data;
1936 
1937     CONCURRENCY_LOCK();
1938 
1939     /* Retrieve native structure address */
1940     nat = nfc_jni_get_nat(e, o);
1941 
1942     /* Create the local semaphore */
1943     if (!nfc_cb_data_init(&cb_data, NULL)) {
1944         goto clean_and_return;
1945     }
1946 
1947     REENTRANCE_LOCK();
1948     ret = phLibNfc_RemoteDev_NtfRegister(&nat->registry_info, nfc_jni_Discovery_notification_callback, (void *)nat);
1949     REENTRANCE_UNLOCK();
1950     if(ret != NFCSTATUS_SUCCESS) {
1951         ALOGD("pphLibNfc_RemoteDev_NtfRegister returned 0x%02x",ret);
1952         goto clean_and_return;
1953     }
1954     TRACE("****** Deselect Secure Element ******");
1955 
1956     TRACE("phLibNfc_SE_SetMode()");
1957     /* Set SE mode - Default */
1958     REENTRANCE_LOCK();
1959     ret = phLibNfc_SE_SetMode(nat->seId, phLibNfc_SE_ActModeDefault,
1960            nfc_jni_se_set_mode_callback, (void *)&cb_data);
1961     REENTRANCE_UNLOCK();
1962 
1963     TRACE("phLibNfc_SE_SetMode returned 0x%02x", ret);
1964     if (ret != NFCSTATUS_PENDING) {
1965         ALOGE("phLibNfc_SE_SetMode() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1966         goto clean_and_return;
1967     }
1968     TRACE("phLibNfc_SE_SetMode() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1969 
1970     /* Wait for callback response */
1971     if (sem_wait(&cb_data.sem)) {
1972         ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
1973         goto clean_and_return;
1974     }
1975 
1976     clean_and_return:
1977     nfc_cb_data_deinit(&cb_data);
1978     CONCURRENCY_UNLOCK();
1979 }
1980 
1981 /* Llcp methods */
1982 
com_android_nfc_NfcManager_doCheckLlcp(JNIEnv * e,jobject o)1983 static jboolean com_android_nfc_NfcManager_doCheckLlcp(JNIEnv *e, jobject o)
1984 {
1985    NFCSTATUS ret;
1986    bool freeData = false;
1987    jboolean result = JNI_FALSE;
1988    struct nfc_jni_native_data *nat;
1989    struct nfc_jni_callback_data  *cb_data;
1990 
1991 
1992    CONCURRENCY_LOCK();
1993 
1994    /* Memory allocation for cb_data
1995     * This is on the heap because it is used by libnfc
1996     * even after this call has succesfully finished. It is only freed
1997     * upon link closure in nfc_jni_llcp_linkStatus_callback.
1998     */
1999    cb_data = (struct nfc_jni_callback_data*) malloc (sizeof(nfc_jni_callback_data));
2000 
2001    /* Retrieve native structure address */
2002    nat = nfc_jni_get_nat(e, o);
2003 
2004    /* Create the local semaphore */
2005    if (!nfc_cb_data_init(cb_data, (void*)nat))
2006    {
2007       goto clean_and_return;
2008    }
2009 
2010    /* Check LLCP compliancy */
2011    TRACE("phLibNfc_Llcp_CheckLlcp(hLlcpHandle=0x%08x)", hLlcpHandle);
2012    REENTRANCE_LOCK();
2013    ret = phLibNfc_Llcp_CheckLlcp(hLlcpHandle,
2014                                  nfc_jni_checkLlcp_callback,
2015                                  nfc_jni_llcp_linkStatus_callback,
2016                                  (void*)cb_data);
2017    REENTRANCE_UNLOCK();
2018    /* In case of a NFCIP return NFCSTATUS_SUCCESS and in case of an another protocol
2019     * NFCSTATUS_PENDING. In this case NFCSTATUS_SUCCESS will also cause the callback. */
2020    if(ret != NFCSTATUS_PENDING && ret != NFCSTATUS_SUCCESS)
2021    {
2022       ALOGE("phLibNfc_Llcp_CheckLlcp() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2023       freeData = true;
2024       goto clean_and_return;
2025    }
2026    TRACE("phLibNfc_Llcp_CheckLlcp() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2027 
2028    /* Wait for callback response */
2029    if(sem_wait(&cb_data->sem))
2030    {
2031       ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
2032       goto clean_and_return;
2033    }
2034 
2035    if(cb_data->status == NFCSTATUS_SUCCESS)
2036    {
2037       result = JNI_TRUE;
2038    }
2039 
2040 clean_and_return:
2041    nfc_cb_data_deinit(cb_data);
2042    if (freeData) {
2043        free(cb_data);
2044    }
2045    CONCURRENCY_UNLOCK();
2046    return result;
2047 }
2048 
com_android_nfc_NfcManager_doActivateLlcp(JNIEnv * e,jobject o)2049 static jboolean com_android_nfc_NfcManager_doActivateLlcp(JNIEnv *e, jobject o)
2050 {
2051    NFCSTATUS ret;
2052    TRACE("phLibNfc_Llcp_Activate(hRemoteDevice=0x%08x)", hLlcpHandle);
2053    REENTRANCE_LOCK();
2054    ret = phLibNfc_Llcp_Activate(hLlcpHandle);
2055    REENTRANCE_UNLOCK();
2056    if(ret == NFCSTATUS_SUCCESS)
2057    {
2058       TRACE("phLibNfc_Llcp_Activate() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2059       return JNI_TRUE;
2060    }
2061    else
2062    {
2063       ALOGE("phLibNfc_Llcp_Activate() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2064       return JNI_FALSE;
2065    }
2066 }
2067 
2068 
2069 
com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket(JNIEnv * e,jobject o,jint nSap,jstring sn)2070 static jobject com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket(JNIEnv *e, jobject o,
2071         jint nSap, jstring sn)
2072 {
2073    NFCSTATUS ret;
2074    jobject connectionlessSocket = NULL;
2075    phLibNfc_Handle hLlcpSocket;
2076    struct nfc_jni_native_data *nat;
2077    phNfc_sData_t sWorkingBuffer = {NULL, 0};
2078    phNfc_sData_t serviceName = {NULL, 0};
2079    phLibNfc_Llcp_sLinkParameters_t sParams;
2080    jclass clsNativeConnectionlessSocket;
2081    jfieldID f;
2082 
2083    /* Retrieve native structure address */
2084    nat = nfc_jni_get_nat(e, o);
2085 
2086    /* Allocate Working buffer length */
2087    phLibNfc_Llcp_GetLocalInfo(hLlcpHandle, &sParams);
2088    sWorkingBuffer.length = sParams.miu + 1; // extra byte for SAP
2089    sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length);
2090 
2091    /* Create socket */
2092    TRACE("phLibNfc_Llcp_Socket(eType=phFriNfc_LlcpTransport_eConnectionLess, ...)");
2093    REENTRANCE_LOCK();
2094    ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionLess,
2095                               NULL,
2096                               &sWorkingBuffer,
2097                               &hLlcpSocket,
2098                               nfc_jni_llcp_transport_socket_err_callback,
2099                               (void*)nat);
2100    REENTRANCE_UNLOCK();
2101 
2102    if(ret != NFCSTATUS_SUCCESS)
2103    {
2104       lastErrorStatus = ret;
2105       ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2106       goto error;
2107    }
2108    TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2109 
2110    /* Service socket */
2111    if (sn == NULL) {
2112        serviceName.buffer = NULL;
2113        serviceName.length = 0;
2114    } else {
2115        serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL);
2116        serviceName.length = (uint32_t)e->GetStringUTFLength(sn);
2117    }
2118 
2119    /* Bind socket */
2120    TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap);
2121    REENTRANCE_LOCK();
2122    ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, &serviceName);
2123    REENTRANCE_UNLOCK();
2124    if(ret != NFCSTATUS_SUCCESS)
2125    {
2126       lastErrorStatus = ret;
2127       ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2128       /* Close socket created */
2129       REENTRANCE_LOCK();
2130       ret = phLibNfc_Llcp_Close(hLlcpSocket);
2131       REENTRANCE_UNLOCK();
2132       goto error;
2133    }
2134    TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2135 
2136 
2137    /* Create new NativeLlcpConnectionlessSocket object */
2138    if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpConnectionlessSocket",&(connectionlessSocket)) == -1)
2139    {
2140       goto error;
2141    }
2142 
2143    /* Get NativeConnectionless class object */
2144    clsNativeConnectionlessSocket = e->GetObjectClass(connectionlessSocket);
2145    if(e->ExceptionCheck())
2146    {
2147       goto error;
2148    }
2149 
2150    /* Set socket handle */
2151    f = e->GetFieldID(clsNativeConnectionlessSocket, "mHandle", "I");
2152    e->SetIntField(connectionlessSocket, f,(jint)hLlcpSocket);
2153    TRACE("Connectionless socket Handle = %02x\n",hLlcpSocket);
2154 
2155    /* Set the miu link of the connectionless socket */
2156    f = e->GetFieldID(clsNativeConnectionlessSocket, "mLinkMiu", "I");
2157    e->SetIntField(connectionlessSocket, f,(jint)PHFRINFC_LLCP_MIU_DEFAULT);
2158    TRACE("Connectionless socket Link MIU = %d\n",PHFRINFC_LLCP_MIU_DEFAULT);
2159 
2160    /* Set socket SAP */
2161    f = e->GetFieldID(clsNativeConnectionlessSocket, "mSap", "I");
2162    e->SetIntField(connectionlessSocket, f,(jint)nSap);
2163    TRACE("Connectionless socket SAP = %d\n",nSap);
2164 
2165    return connectionlessSocket;
2166 error:
2167    if (serviceName.buffer != NULL) {
2168       e->ReleaseStringUTFChars(sn, (const char *)serviceName.buffer);
2169    }
2170 
2171    if (sWorkingBuffer.buffer != NULL) {
2172        free(sWorkingBuffer.buffer);
2173    }
2174 
2175    return NULL;
2176 }
2177 
com_android_nfc_NfcManager_doCreateLlcpServiceSocket(JNIEnv * e,jobject o,jint nSap,jstring sn,jint miu,jint rw,jint linearBufferLength)2178 static jobject com_android_nfc_NfcManager_doCreateLlcpServiceSocket(JNIEnv *e, jobject o, jint nSap, jstring sn, jint miu, jint rw, jint linearBufferLength)
2179 {
2180    NFCSTATUS ret;
2181    phLibNfc_Handle hLlcpSocket;
2182    phLibNfc_Llcp_sSocketOptions_t sOptions;
2183    phNfc_sData_t sWorkingBuffer;
2184    phNfc_sData_t serviceName;
2185    struct nfc_jni_native_data *nat;
2186    jobject serviceSocket = NULL;
2187    jclass clsNativeLlcpServiceSocket;
2188    jfieldID f;
2189 
2190    /* Retrieve native structure address */
2191    nat = nfc_jni_get_nat(e, o);
2192 
2193    /* Set Connection Oriented socket options */
2194    sOptions.miu = miu;
2195    sOptions.rw  = rw;
2196 
2197    /* Allocate Working buffer length */
2198    sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength;
2199    sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length);
2200 
2201 
2202    /* Create socket */
2203    TRACE("phLibNfc_Llcp_Socket(hRemoteDevice=0x%08x, eType=phFriNfc_LlcpTransport_eConnectionOriented, ...)", hLlcpHandle);
2204    REENTRANCE_LOCK();
2205    ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionOriented,
2206                               &sOptions,
2207                               &sWorkingBuffer,
2208                               &hLlcpSocket,
2209                               nfc_jni_llcp_transport_socket_err_callback,
2210                               (void*)nat);
2211    REENTRANCE_UNLOCK();
2212 
2213    if(ret != NFCSTATUS_SUCCESS)
2214    {
2215       ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2216       lastErrorStatus = ret;
2217       goto error;
2218    }
2219    TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2220 
2221    /* Service socket */
2222    if (sn == NULL) {
2223        serviceName.buffer = NULL;
2224        serviceName.length = 0;
2225    } else {
2226        serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL);
2227        serviceName.length = (uint32_t)e->GetStringUTFLength(sn);
2228    }
2229 
2230    /* Bind socket */
2231    TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap);
2232    REENTRANCE_LOCK();
2233    ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, &serviceName);
2234    REENTRANCE_UNLOCK();
2235    if(ret != NFCSTATUS_SUCCESS)
2236    {
2237       lastErrorStatus = ret;
2238       ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2239       /* Close socket created */
2240       ret = phLibNfc_Llcp_Close(hLlcpSocket);
2241       goto error;
2242    }
2243    TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2244 
2245    TRACE("phLibNfc_Llcp_Listen(hSocket=0x%08x, ...)", hLlcpSocket);
2246    REENTRANCE_LOCK();
2247    ret = phLibNfc_Llcp_Listen( hLlcpSocket,
2248                                nfc_jni_llcp_transport_listen_socket_callback,
2249                                (void*)hLlcpSocket);
2250    REENTRANCE_UNLOCK();
2251 
2252    if(ret != NFCSTATUS_SUCCESS)
2253    {
2254       ALOGE("phLibNfc_Llcp_Listen() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2255       lastErrorStatus = ret;
2256       /* Close created socket */
2257       REENTRANCE_LOCK();
2258       ret = phLibNfc_Llcp_Close(hLlcpSocket);
2259       REENTRANCE_UNLOCK();
2260       goto error;
2261    }
2262    TRACE("phLibNfc_Llcp_Listen() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2263 
2264    /* Create new NativeLlcpServiceSocket object */
2265    if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpServiceSocket",&(serviceSocket)) == -1)
2266    {
2267       ALOGE("Llcp Socket object creation error");
2268       goto error;
2269    }
2270 
2271    /* Get NativeLlcpServiceSocket class object */
2272    clsNativeLlcpServiceSocket = e->GetObjectClass(serviceSocket);
2273    if(e->ExceptionCheck())
2274    {
2275       ALOGE("Llcp Socket get object class error");
2276       goto error;
2277    }
2278 
2279    /* Set socket handle */
2280    f = e->GetFieldID(clsNativeLlcpServiceSocket, "mHandle", "I");
2281    e->SetIntField(serviceSocket, f,(jint)hLlcpSocket);
2282    TRACE("Service socket Handle = %02x\n",hLlcpSocket);
2283 
2284    /* Set socket linear buffer length */
2285    f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalLinearBufferLength", "I");
2286    e->SetIntField(serviceSocket, f,(jint)linearBufferLength);
2287    TRACE("Service socket Linear buffer length = %02x\n",linearBufferLength);
2288 
2289    /* Set socket MIU */
2290    f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalMiu", "I");
2291    e->SetIntField(serviceSocket, f,(jint)miu);
2292    TRACE("Service socket MIU = %d\n",miu);
2293 
2294    /* Set socket RW */
2295    f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalRw", "I");
2296    e->SetIntField(serviceSocket, f,(jint)rw);
2297    TRACE("Service socket RW = %d\n",rw);
2298 
2299    return serviceSocket;
2300 error:
2301    if (serviceName.buffer != NULL) {
2302       e->ReleaseStringUTFChars(sn, (const char *)serviceName.buffer);
2303    }
2304    return NULL;
2305 }
2306 
com_android_nfc_NfcManager_doCreateLlcpSocket(JNIEnv * e,jobject o,jint nSap,jint miu,jint rw,jint linearBufferLength)2307 static jobject com_android_nfc_NfcManager_doCreateLlcpSocket(JNIEnv *e, jobject o, jint nSap, jint miu, jint rw, jint linearBufferLength)
2308 {
2309    jobject clientSocket = NULL;
2310    NFCSTATUS ret;
2311    phLibNfc_Handle hLlcpSocket;
2312    phLibNfc_Llcp_sSocketOptions_t sOptions;
2313    phNfc_sData_t sWorkingBuffer;
2314    struct nfc_jni_native_data *nat;
2315    jclass clsNativeLlcpSocket;
2316    jfieldID f;
2317 
2318    /* Retrieve native structure address */
2319    nat = nfc_jni_get_nat(e, o);
2320 
2321    /* Set Connection Oriented socket options */
2322    sOptions.miu = miu;
2323    sOptions.rw  = rw;
2324 
2325    /* Allocate Working buffer length */
2326    sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength;
2327    sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length);
2328 
2329    /* Create socket */
2330    TRACE("phLibNfc_Llcp_Socket(eType=phFriNfc_LlcpTransport_eConnectionOriented, ...)");
2331    REENTRANCE_LOCK();
2332    ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionOriented,
2333                               &sOptions,
2334                               &sWorkingBuffer,
2335                               &hLlcpSocket,
2336                               nfc_jni_llcp_transport_socket_err_callback,
2337                               (void*)nat);
2338    REENTRANCE_UNLOCK();
2339 
2340    if(ret != NFCSTATUS_SUCCESS)
2341    {
2342       ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2343       lastErrorStatus = ret;
2344       return NULL;
2345    }
2346    TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2347 
2348    /* Create new NativeLlcpSocket object */
2349    if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpSocket",&(clientSocket)) == -1)
2350    {
2351       ALOGE("Llcp socket object creation error");
2352       return NULL;
2353    }
2354 
2355    /* Get NativeConnectionless class object */
2356    clsNativeLlcpSocket = e->GetObjectClass(clientSocket);
2357    if(e->ExceptionCheck())
2358    {
2359       ALOGE("Get class object error");
2360       return NULL;
2361    }
2362 
2363    /* Test if an SAP number is present */
2364    if(nSap != 0)
2365    {
2366       /* Bind socket */
2367       TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap);
2368       REENTRANCE_LOCK();
2369       ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, NULL);
2370       REENTRANCE_UNLOCK();
2371       if(ret != NFCSTATUS_SUCCESS)
2372       {
2373          lastErrorStatus = ret;
2374          ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2375          /* Close socket created */
2376          REENTRANCE_LOCK();
2377          ret = phLibNfc_Llcp_Close(hLlcpSocket);
2378          REENTRANCE_UNLOCK();
2379          return NULL;
2380       }
2381       TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2382 
2383       /* Set socket SAP */
2384       f = e->GetFieldID(clsNativeLlcpSocket, "mSap", "I");
2385       e->SetIntField(clientSocket, f,(jint)nSap);
2386       TRACE("socket SAP = %d\n",nSap);
2387    }
2388 
2389    /* Set socket handle */
2390    f = e->GetFieldID(clsNativeLlcpSocket, "mHandle", "I");
2391    e->SetIntField(clientSocket, f,(jint)hLlcpSocket);
2392    TRACE("socket Handle = %02x\n",hLlcpSocket);
2393 
2394    /* Set socket MIU */
2395    f = e->GetFieldID(clsNativeLlcpSocket, "mLocalMiu", "I");
2396    e->SetIntField(clientSocket, f,(jint)miu);
2397    TRACE("socket MIU = %d\n",miu);
2398 
2399    /* Set socket RW */
2400    f = e->GetFieldID(clsNativeLlcpSocket, "mLocalRw", "I");
2401    e->SetIntField(clientSocket, f,(jint)rw);
2402    TRACE("socket RW = %d\n",rw);
2403 
2404 
2405    return clientSocket;
2406 }
2407 
com_android_nfc_NfcManager_doGetLastError(JNIEnv * e,jobject o)2408 static jint com_android_nfc_NfcManager_doGetLastError(JNIEnv *e, jobject o)
2409 {
2410    TRACE("Last Error Status = 0x%02x",lastErrorStatus);
2411 
2412    if(lastErrorStatus == NFCSTATUS_BUFFER_TOO_SMALL)
2413    {
2414       return ERROR_BUFFER_TOO_SMALL;
2415    }
2416    else if(lastErrorStatus == NFCSTATUS_INSUFFICIENT_RESOURCES)
2417    {
2418       return  ERROR_INSUFFICIENT_RESOURCES;
2419    }
2420    else
2421    {
2422       return lastErrorStatus;
2423    }
2424 }
2425 
com_android_nfc_NfcManager_doAbort(JNIEnv * e,jobject o)2426 static void com_android_nfc_NfcManager_doAbort(JNIEnv *e, jobject o)
2427 {
2428     emergency_recovery(NULL);
2429 }
2430 
com_android_nfc_NfcManager_doEnableReaderMode(JNIEnv * e,jobject o,jint modes)2431 static void com_android_nfc_NfcManager_doEnableReaderMode(JNIEnv *e, jobject o,
2432         jint modes)
2433 {
2434     struct nfc_jni_native_data *nat = NULL;
2435     nat = nfc_jni_get_nat(e, o);
2436     CONCURRENCY_LOCK();
2437     nat->p2p_initiator_modes = 0;
2438     nat->p2p_target_modes = 0;
2439     nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = TRUE;
2440     nat->discovery_cfg.Duration = 200000; /* in ms */
2441     nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A = (modes & 0x01) != 0;
2442     nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B = (modes & 0x02) != 0;
2443     nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212 = (modes & 0x04) != 0;
2444     nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424 = (modes & 0x04) != 0;
2445     nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693 = (modes & 0x08) != 0;
2446     nfc_jni_start_discovery_locked(nat, FALSE);
2447     CONCURRENCY_UNLOCK();
2448 }
2449 
com_android_nfc_NfcManager_doDisableReaderMode(JNIEnv * e,jobject o)2450 static void com_android_nfc_NfcManager_doDisableReaderMode(JNIEnv *e, jobject o)
2451 {
2452     struct nfc_jni_native_data *nat = NULL;
2453     nat = nfc_jni_get_nat(e, o);
2454     CONCURRENCY_LOCK();
2455     nat->p2p_initiator_modes = phNfc_eP2P_ALL;
2456     nat->p2p_target_modes = 0x0E; // All passive except 106, active
2457     nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = FALSE;
2458     nat->discovery_cfg.Duration = 300000; /* in ms */
2459     nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A = TRUE;
2460     nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B = TRUE;
2461     nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212 = TRUE;
2462     nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424 = TRUE;
2463     nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693 = TRUE;
2464     nfc_jni_start_discovery_locked(nat, FALSE);
2465     CONCURRENCY_UNLOCK();
2466 }
2467 
com_android_nfc_NfcManager_doSetP2pInitiatorModes(JNIEnv * e,jobject o,jint modes)2468 static void com_android_nfc_NfcManager_doSetP2pInitiatorModes(JNIEnv *e, jobject o,
2469         jint modes)
2470 {
2471     ALOGE("Setting init modes to %x", modes);
2472     struct nfc_jni_native_data *nat = NULL;
2473     nat = nfc_jni_get_nat(e, o);
2474     nat->p2p_initiator_modes = modes;
2475 }
2476 
com_android_nfc_NfcManager_doSetP2pTargetModes(JNIEnv * e,jobject o,jint modes)2477 static void com_android_nfc_NfcManager_doSetP2pTargetModes(JNIEnv *e, jobject o,
2478         jint modes)
2479 {
2480     ALOGE("Setting target modes to %x", modes);
2481     struct nfc_jni_native_data *nat = NULL;
2482     nat = nfc_jni_get_nat(e, o);
2483     nat->p2p_target_modes = modes;
2484 }
2485 
performDownload(struct nfc_jni_native_data * nat,bool takeLock)2486 static bool performDownload(struct nfc_jni_native_data* nat, bool takeLock) {
2487     bool result = FALSE;
2488     int load_result;
2489     bool wasDisabled = FALSE;
2490     uint8_t OutputBuffer[1];
2491     uint8_t InputBuffer[1];
2492     NFCSTATUS status = NFCSTATUS_FAILED;
2493     struct nfc_jni_callback_data cb_data;
2494 
2495     /* Create the local semaphore */
2496     if (!nfc_cb_data_init(&cb_data, NULL))
2497     {
2498        result = FALSE;
2499        goto clean_and_return;
2500     }
2501 
2502     if (takeLock)
2503     {
2504         CONCURRENCY_LOCK();
2505     }
2506 
2507     /* Initialize Driver */
2508     if(!driverConfigured)
2509     {
2510         result = nfc_jni_configure_driver(nat);
2511         wasDisabled = TRUE;
2512     }
2513     TRACE("com_android_nfc_NfcManager_doDownload()");
2514 
2515     TRACE("Go in Download Mode");
2516     phLibNfc_Download_Mode();
2517 
2518     TRACE("Load new Firmware Image");
2519     load_result = phLibNfc_Load_Firmware_Image();
2520     if(load_result != 0)
2521     {
2522         TRACE("Load new Firmware Image - status = %d",load_result);
2523         result = FALSE;
2524         goto clean_and_return;
2525     }
2526 
2527     // Download
2528     gInputParam.buffer  = InputBuffer;
2529     gInputParam.length  = 0x01;
2530     gOutputParam.buffer = OutputBuffer;
2531     gOutputParam.length = 0x01;
2532 
2533     ALOGD("Download new Firmware");
2534     REENTRANCE_LOCK();
2535     status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_FW_DOWNLOAD, &gInputParam, &gOutputParam, nfc_jni_ioctl_callback, (void *)&cb_data);
2536     REENTRANCE_UNLOCK();
2537     if(status != NFCSTATUS_PENDING)
2538     {
2539         ALOGE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
2540         result = FALSE;
2541         goto clean_and_return;
2542     }
2543     TRACE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
2544 
2545     /* Wait for callback response */
2546     if(sem_wait(&cb_data.sem))
2547     {
2548        ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
2549        result = FALSE;
2550        goto clean_and_return;
2551     }
2552 
2553     /* NOTE: we will get NFCSTATUS_FEATURE_NOT_SUPPORTED when we
2554        try to download an old-style firmware on top of a new-style
2555        firmware.  Hence, this is expected behavior, and not an
2556        error condition. */
2557     if(cb_data.status != NFCSTATUS_SUCCESS && cb_data.status != NFCSTATUS_FEATURE_NOT_SUPPORTED)
2558     {
2559         TRACE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
2560         result = FALSE;
2561         goto clean_and_return;
2562     }
2563 
2564     if(cb_data.status == NFCSTATUS_FEATURE_NOT_SUPPORTED)
2565     {
2566         ALOGW("Old-style firmware not installed on top of new-style firmware. Using existing firmware in the chip.");
2567     }
2568 
2569     /*Download is successful*/
2570     result = TRUE;
2571 clean_and_return:
2572     TRACE("phLibNfc_HW_Reset()");
2573     phLibNfc_HW_Reset();
2574     /* Deinitialize Driver */
2575     if(wasDisabled)
2576     {
2577         result = nfc_jni_unconfigure_driver(nat);
2578     }
2579     if (takeLock)
2580     {
2581         CONCURRENCY_UNLOCK();
2582     }
2583     nfc_cb_data_deinit(&cb_data);
2584     return result;
2585 }
2586 
com_android_nfc_NfcManager_doDownload(JNIEnv * e,jobject o)2587 static jboolean com_android_nfc_NfcManager_doDownload(JNIEnv *e, jobject o)
2588 {
2589     struct nfc_jni_native_data *nat = NULL;
2590     nat = nfc_jni_get_nat(e, o);
2591     return performDownload(nat, true);
2592 }
2593 
com_android_nfc_NfcManager_doDump(JNIEnv * e,jobject o)2594 static jstring com_android_nfc_NfcManager_doDump(JNIEnv *e, jobject o)
2595 {
2596     char buffer[100];
2597     snprintf(buffer, sizeof(buffer), "libnfc llc error_count=%u", libnfc_llc_error_count);
2598     return e->NewStringUTF(buffer);
2599 }
2600 
2601 /*
2602  * JNI registration.
2603  */
2604 static JNINativeMethod gMethods[] =
2605 {
2606    {"doDownload", "()Z",
2607         (void *)com_android_nfc_NfcManager_doDownload},
2608 
2609    {"initializeNativeStructure", "()Z",
2610       (void *)com_android_nfc_NfcManager_init_native_struc},
2611 
2612    {"doInitialize", "()Z",
2613       (void *)com_android_nfc_NfcManager_initialize},
2614 
2615    {"doDeinitialize", "()Z",
2616       (void *)com_android_nfc_NfcManager_deinitialize},
2617 
2618    {"enableDiscovery", "()V",
2619       (void *)com_android_nfc_NfcManager_enableDiscovery},
2620 
2621    {"doGetSecureElementList", "()[I",
2622       (void *)com_android_nfc_NfcManager_doGetSecureElementList},
2623 
2624    {"doSelectSecureElement", "()V",
2625       (void *)com_android_nfc_NfcManager_doSelectSecureElement},
2626 
2627    {"doDeselectSecureElement", "()V",
2628       (void *)com_android_nfc_NfcManager_doDeselectSecureElement},
2629 
2630    {"doCheckLlcp", "()Z",
2631       (void *)com_android_nfc_NfcManager_doCheckLlcp},
2632 
2633    {"doActivateLlcp", "()Z",
2634       (void *)com_android_nfc_NfcManager_doActivateLlcp},
2635 
2636    {"doCreateLlcpConnectionlessSocket", "(ILjava/lang/String;)Lcom/android/nfc/dhimpl/NativeLlcpConnectionlessSocket;",
2637       (void *)com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket},
2638 
2639    {"doCreateLlcpServiceSocket", "(ILjava/lang/String;III)Lcom/android/nfc/dhimpl/NativeLlcpServiceSocket;",
2640       (void *)com_android_nfc_NfcManager_doCreateLlcpServiceSocket},
2641 
2642    {"doCreateLlcpSocket", "(IIII)Lcom/android/nfc/dhimpl/NativeLlcpSocket;",
2643       (void *)com_android_nfc_NfcManager_doCreateLlcpSocket},
2644 
2645    {"doGetLastError", "()I",
2646       (void *)com_android_nfc_NfcManager_doGetLastError},
2647 
2648    {"disableDiscovery", "()V",
2649       (void *)com_android_nfc_NfcManager_disableDiscovery},
2650 
2651    {"doSetTimeout", "(II)Z",
2652       (void *)com_android_nfc_NfcManager_doSetTimeout},
2653 
2654    {"doGetTimeout", "(I)I",
2655       (void *)com_android_nfc_NfcManager_doGetTimeout},
2656 
2657    {"doResetTimeouts", "()V",
2658       (void *)com_android_nfc_NfcManager_doResetTimeouts},
2659 
2660    {"doAbort", "()V",
2661       (void *)com_android_nfc_NfcManager_doAbort},
2662 
2663    {"doSetP2pInitiatorModes","(I)V",
2664       (void *)com_android_nfc_NfcManager_doSetP2pInitiatorModes},
2665 
2666    {"doSetP2pTargetModes","(I)V",
2667       (void *)com_android_nfc_NfcManager_doSetP2pTargetModes},
2668 
2669    {"doEnableReaderMode","(I)V",
2670       (void *)com_android_nfc_NfcManager_doEnableReaderMode},
2671 
2672    {"doDisableReaderMode","()V",
2673       (void *)com_android_nfc_NfcManager_doDisableReaderMode},
2674 
2675    {"doDump", "()Ljava/lang/String;",
2676       (void *)com_android_nfc_NfcManager_doDump},
2677 };
2678 
2679 
register_com_android_nfc_NativeNfcManager(JNIEnv * e)2680 int register_com_android_nfc_NativeNfcManager(JNIEnv *e)
2681 {
2682     nfc_jni_native_monitor_t *nfc_jni_native_monitor;
2683 
2684    nfc_jni_native_monitor = nfc_jni_init_monitor();
2685    if(nfc_jni_native_monitor == NULL)
2686    {
2687       ALOGE("NFC Manager cannot recover native monitor %x\n", errno);
2688       return -1;
2689    }
2690 
2691    return jniRegisterNativeMethods(e,
2692       "com/android/nfc/dhimpl/NativeNfcManager",
2693       gMethods, NELEM(gMethods));
2694 }
2695 
2696 } /* namespace android */
2697