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