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