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