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