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                         if (TRACE_ENABLED == 1) {
   1168                             char aid_str[AID_MAXLEN * 2 + 1];
   1169                             aid_str[0] = '\0';
   1170                             for (i = 0; i < (int) (aid->length) && i < AID_MAXLEN; i++) {
   1171                               snprintf(&aid_str[i*2], 3, "%02x", aid->buffer[i]);
   1172                             }
   1173                             ALOGD("> AID: %s", aid_str);
   1174                         }
   1175                         tmp_array = e->NewByteArray(aid->length);
   1176                         if (tmp_array == NULL)
   1177                         {
   1178                             goto error;
   1179                         }
   1180 
   1181                         e->SetByteArrayRegion((jbyteArray)tmp_array, 0, aid->length, (jbyte *)aid->buffer);
   1182                         if(e->ExceptionCheck())
   1183                         {
   1184                             goto error;
   1185                         }
   1186                     }
   1187                     else
   1188                     {
   1189                         goto error;
   1190                     }
   1191 
   1192                     TRACE("Notify Nfc Service");
   1193                     /* Notify manager that a new event occurred on a SE */
   1194                     e->CallVoidMethod(nat->manager, cached_NfcManager_notifyTransactionListeners, tmp_array);
   1195                     if(e->ExceptionCheck())
   1196                     {
   1197                         goto error;
   1198                     }
   1199                 }
   1200                 else
   1201                 {
   1202                     ALOGD("> NO AID DETECTED");
   1203                 }
   1204             }break;
   1205 
   1206             case phLibNfc_eSE_EvtApduReceived:
   1207             {
   1208                 phNfc_sData_t *apdu = &(evt_info->UiccEvtInfo.aid);
   1209                 TRACE("> SE EVT_APDU_RECEIVED");
   1210 
   1211                 if (apdu != NULL) {
   1212                         TRACE("  APDU length=%d", apdu->length);
   1213                         tmp_array = e->NewByteArray(apdu->length);
   1214                         if (tmp_array == NULL) {
   1215                             goto error;
   1216                         }
   1217                         e->SetByteArrayRegion((jbyteArray)tmp_array, 0, apdu->length, (jbyte *)apdu->buffer);
   1218                         if (e->ExceptionCheck()) {
   1219                             goto error;
   1220                         }
   1221                 } else {
   1222                         TRACE("  APDU EMPTY");
   1223                 }
   1224 
   1225                 TRACE("Notify Nfc Service");
   1226                 e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeApduReceived, tmp_array);
   1227             }break;
   1228 
   1229             case phLibNfc_eSE_EvtCardRemoval:
   1230             {
   1231                 TRACE("> SE EVT_EMV_CARD_REMOVAL");
   1232                 TRACE("Notify Nfc Service");
   1233                 e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeEmvCardRemoval);
   1234             }break;
   1235 
   1236             case phLibNfc_eSE_EvtMifareAccess:
   1237             {
   1238                 TRACE("> SE EVT_MIFARE_ACCESS");
   1239                 mifare_command = &(evt_info->UiccEvtInfo.aid);
   1240                 TRACE("> MIFARE Block: %d",mifare_command->buffer[1]);
   1241                 tmp_array = e->NewByteArray(2);
   1242                 if (tmp_array == NULL)
   1243                 {
   1244                     goto error;
   1245                 }
   1246 
   1247                 e->SetByteArrayRegion((jbyteArray)tmp_array, 0, 2, (jbyte *)mifare_command->buffer);
   1248                 if(e->ExceptionCheck())
   1249                 {
   1250                     goto error;
   1251                 }
   1252                 TRACE("Notify Nfc Service");
   1253                 e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeMifareAccess, mifare_block);
   1254             }break;
   1255 
   1256             case phLibNfc_eSE_EvtFieldOn:
   1257             {
   1258                 TRACE("> SE EVT_FIELD_ON");
   1259                 TRACE("Notify Nfc Service");
   1260                 e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeFieldActivated);
   1261             }break;
   1262 
   1263             case phLibNfc_eSE_EvtFieldOff:
   1264             {
   1265                 TRACE("> SE EVT_FIELD_OFF");
   1266                 TRACE("Notify Nfc Service");
   1267                 e->CallVoidMethod(nat->manager, cached_NfcManager_notifySeFieldDeactivated);
   1268             }break;
   1269 
   1270             default:
   1271             {
   1272                 TRACE("Unknown SE event");
   1273             }break;
   1274         }
   1275     }
   1276     else
   1277     {
   1278         ALOGE("SE transaction notification error");
   1279         goto error;
   1280     }
   1281 
   1282     /* Function finished, now clean and return */
   1283     goto clean_and_return;
   1284 
   1285  error:
   1286     /* In case of error, just discard the notification */
   1287     ALOGE("Failed to send SE transaction notification");
   1288     e->ExceptionClear();
   1289 
   1290  clean_and_return:
   1291     if(tmp_array != NULL)
   1292     {
   1293        e->DeleteLocalRef(tmp_array);
   1294     }
   1295 }
   1296 
   1297 static void nfc_jni_se_set_mode_callback(void *pContext,
   1298    phLibNfc_Handle handle, NFCSTATUS status)
   1299 {
   1300    struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
   1301 
   1302    LOG_CALLBACK("nfc_jni_se_set_mode_callback", status);
   1303 
   1304    pContextData->status = status;
   1305    sem_post(&pContextData->sem);
   1306 }
   1307 
   1308 /*
   1309  * NFCManager methods
   1310  */
   1311 
   1312 static void nfc_jni_start_discovery_locked(struct nfc_jni_native_data *nat, bool resume)
   1313 {
   1314    NFCSTATUS ret;
   1315    struct nfc_jni_callback_data cb_data;
   1316 
   1317    /* Create the local semaphore */
   1318    if (!nfc_cb_data_init(&cb_data, NULL))
   1319    {
   1320       goto clean_and_return;
   1321    }
   1322    /* Reset the PN544 ISO XCHG / sw watchdog timeouts */
   1323    nfc_jni_reset_timeout_values();
   1324 
   1325    /* Reload the p2p modes */
   1326    nat->discovery_cfg.NfcIP_Mode = nat->p2p_initiator_modes;  //initiator
   1327    nat->discovery_cfg.NfcIP_Target_Mode = nat->p2p_target_modes;  //target
   1328    nat->discovery_cfg.NfcIP_Tgt_Disable = FALSE;
   1329 
   1330    /* Reset device connected flag */
   1331    device_connected_flag = 0;
   1332 
   1333    /* Start Polling loop */
   1334    TRACE("******  Start NFC Discovery ******");
   1335    REENTRANCE_LOCK();
   1336    ret = phLibNfc_Mgt_ConfigureDiscovery(resume ? NFC_DISCOVERY_RESUME : NFC_DISCOVERY_CONFIG,
   1337       nat->discovery_cfg, nfc_jni_discover_callback, (void *)&cb_data);
   1338    REENTRANCE_UNLOCK();
   1339    TRACE("phLibNfc_Mgt_ConfigureDiscovery(%s-%s-%s-%s-%s-%s, %s-%x-%x) returned 0x%08x\n",
   1340       nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A==TRUE?"3A":"",
   1341       nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B==TRUE?"3B":"",
   1342       nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212==TRUE?"F2":"",
   1343       nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424==TRUE?"F4":"",
   1344       nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive==TRUE?"NFC":"",
   1345       nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693==TRUE?"RFID":"",
   1346       nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation==FALSE?"CE":"",
   1347       nat->discovery_cfg.NfcIP_Mode, nat->discovery_cfg.Duration, ret);
   1348 
   1349    if(ret != NFCSTATUS_PENDING)
   1350    {
   1351       emergency_recovery(nat);
   1352       goto clean_and_return;
   1353    }
   1354 
   1355    /* Wait for callback response */
   1356    if(sem_wait(&cb_data.sem))
   1357    {
   1358       ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
   1359       goto clean_and_return;
   1360    }
   1361 
   1362 clean_and_return:
   1363    nfc_cb_data_deinit(&cb_data);
   1364 }
   1365 
   1366 static void nfc_jni_stop_discovery_locked(struct nfc_jni_native_data *nat)
   1367 {
   1368    phLibNfc_sADD_Cfg_t discovery_cfg;
   1369    NFCSTATUS ret;
   1370    struct nfc_jni_callback_data cb_data;
   1371 
   1372    /* Create the local semaphore */
   1373    if (!nfc_cb_data_init(&cb_data, NULL))
   1374    {
   1375       goto clean_and_return;
   1376    }
   1377 
   1378    discovery_cfg.PollDevInfo.PollEnabled = 0;
   1379    discovery_cfg.NfcIP_Mode = phNfc_eDefaultP2PMode;
   1380    discovery_cfg.NfcIP_Target_Mode = 0;
   1381    discovery_cfg.NfcIP_Tgt_Disable = TRUE;
   1382 
   1383    /* Start Polling loop */
   1384    TRACE("******  Stop NFC Discovery ******");
   1385    REENTRANCE_LOCK();
   1386    ret = phLibNfc_Mgt_ConfigureDiscovery(NFC_DISCOVERY_CONFIG,discovery_cfg, nfc_jni_discover_callback, (void *)&cb_data);
   1387    REENTRANCE_UNLOCK();
   1388    TRACE("phLibNfc_Mgt_ConfigureDiscovery(%s-%s-%s-%s-%s-%s, %s-%x-%x) returned 0x%08x\n",
   1389       discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A==TRUE?"3A":"",
   1390       discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B==TRUE?"3B":"",
   1391       discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212==TRUE?"F2":"",
   1392       discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424==TRUE?"F4":"",
   1393       discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive==TRUE?"NFC":"",
   1394       discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693==TRUE?"RFID":"",
   1395       discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation==FALSE?"CE":"",
   1396       discovery_cfg.NfcIP_Mode, discovery_cfg.Duration, ret);
   1397 
   1398    if(ret != NFCSTATUS_PENDING)
   1399    {
   1400       emergency_recovery(nat);
   1401    }
   1402 
   1403    /* Wait for callback response */
   1404    if(sem_wait(&cb_data.sem))
   1405    {
   1406       ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
   1407       goto clean_and_return;
   1408    }
   1409 
   1410 clean_and_return:
   1411    nfc_cb_data_deinit(&cb_data);
   1412 }
   1413 
   1414 
   1415 static void com_android_nfc_NfcManager_disableDiscovery(JNIEnv *e, jobject o)
   1416 {
   1417     struct nfc_jni_native_data *nat;
   1418 
   1419     CONCURRENCY_LOCK();
   1420 
   1421     /* Retrieve native structure address */
   1422     nat = nfc_jni_get_nat(e, o);
   1423 
   1424     nfc_jni_stop_discovery_locked(nat);
   1425 
   1426     CONCURRENCY_UNLOCK();
   1427 
   1428 }
   1429 
   1430 static void com_android_nfc_NfcManager_enableDiscovery(JNIEnv *e, jobject o) {
   1431     NFCSTATUS ret;
   1432     struct nfc_jni_native_data *nat;
   1433 
   1434     CONCURRENCY_LOCK();
   1435 
   1436     nat = nfc_jni_get_nat(e, o);
   1437 
   1438    /* Register callback for remote device notifications.
   1439     * Must re-register every time we turn on discovery, since other operations
   1440     * (such as opening the Secure Element) can change the remote device
   1441     * notification callback*/
   1442    REENTRANCE_LOCK();
   1443    ret = phLibNfc_RemoteDev_NtfRegister(&nat->registry_info, nfc_jni_Discovery_notification_callback, (void *)nat);
   1444    REENTRANCE_UNLOCK();
   1445    if(ret != NFCSTATUS_SUCCESS)
   1446    {
   1447         ALOGD("pphLibNfc_RemoteDev_NtfRegister returned 0x%02x",ret);
   1448         goto clean_and_return;
   1449    }
   1450    TRACE("phLibNfc_RemoteDev_NtfRegister(%s-%s-%s-%s-%s-%s-%s-%s) returned 0x%x\n",
   1451       nat->registry_info.Jewel==TRUE?"J":"",
   1452       nat->registry_info.MifareUL==TRUE?"UL":"",
   1453       nat->registry_info.MifareStd==TRUE?"Mi":"",
   1454       nat->registry_info.Felica==TRUE?"F":"",
   1455       nat->registry_info.ISO14443_4A==TRUE?"4A":"",
   1456       nat->registry_info.ISO14443_4B==TRUE?"4B":"",
   1457       nat->registry_info.NFC==TRUE?"P2P":"",
   1458       nat->registry_info.ISO15693==TRUE?"R":"", ret);
   1459 
   1460     nfc_jni_start_discovery_locked(nat, false);
   1461 clean_and_return:
   1462     CONCURRENCY_UNLOCK();
   1463 }
   1464 
   1465 static void com_android_nfc_NfcManager_doResetTimeouts( JNIEnv *e, jobject o) {
   1466     CONCURRENCY_LOCK();
   1467     nfc_jni_reset_timeout_values();
   1468     CONCURRENCY_UNLOCK();
   1469 }
   1470 
   1471 static void setFelicaTimeout(jint timeout) {
   1472    // The Felica timeout is configurable in the PN544 upto a maximum of 255 ms.
   1473    // It can be set to 0 to disable the timeout altogether, in which case we
   1474    // use the sw watchdog as a fallback.
   1475    if (timeout <= 255) {
   1476        phLibNfc_SetFelicaTimeout(timeout);
   1477    } else {
   1478        // Disable hw timeout, use sw watchdog for timeout
   1479        phLibNfc_SetFelicaTimeout(0);
   1480        phLibNfc_SetHciTimeout(timeout);
   1481    }
   1482 
   1483 }
   1484 // Calculates ceiling log2 of value
   1485 static unsigned int log2(int value) {
   1486     unsigned int ret = 0;
   1487     bool isPowerOf2 = ((value & (value - 1)) == 0);
   1488     while ( (value >> ret) > 1 ) ret++;
   1489     if (!isPowerOf2) ret++;
   1490     return ret;
   1491 }
   1492 
   1493 // The Iso/Mifare Xchg timeout in PN544 is a non-linear function over X
   1494 // spanning 0 - 4.9s: timeout in seconds = (256 * 16 / 13560000) * 2 ^ X
   1495 //
   1496 // We keep the constant part of the formula in a static; note the factor
   1497 // 1000 off, which is due to the fact that the formula calculates seconds,
   1498 // but this method gets milliseconds as an argument.
   1499 static double nxp_nfc_timeout_factor = (256 * 16) / 13560.0;
   1500 
   1501 static int calcTimeout(int timeout_in_ms) {
   1502    // timeout = (256 * 16 / 13560000) * 2 ^ X
   1503    // First find the first X for which timeout > requested timeout
   1504    return (log2(ceil(((double) timeout_in_ms) / nxp_nfc_timeout_factor)));
   1505 }
   1506 
   1507 static void setIsoDepTimeout(jint timeout) {
   1508    if (timeout <= 4900) {
   1509        int value = calcTimeout(timeout);
   1510        // Then re-compute the actual timeout based on X
   1511        double actual_timeout = nxp_nfc_timeout_factor * (1 << value);
   1512        // Set the sw watchdog a bit longer (The PN544 timeout is very accurate,
   1513        // but it will take some time to get back through the sw layers.
   1514        // 500 ms should be enough).
   1515        phLibNfc_SetHciTimeout(ceil(actual_timeout + 500));
   1516        value |= 0x10; // bit 4 to enable timeout
   1517        phLibNfc_SetIsoXchgTimeout(value);
   1518    }
   1519    else {
   1520        // Also note that if we desire a timeout > 4.9s, the Iso Xchg timeout
   1521        // must be disabled completely, to prevent the PN544 from aborting
   1522        // the transaction. We reuse the HCI sw watchdog to catch the timeout
   1523        // in that case.
   1524        phLibNfc_SetIsoXchgTimeout(0x00);
   1525        phLibNfc_SetHciTimeout(timeout);
   1526    }
   1527 }
   1528 
   1529 static void setNfcATimeout(jint timeout) {
   1530    if (timeout <= 4900) {
   1531        int value = calcTimeout(timeout);
   1532        phLibNfc_SetMifareRawTimeout(value);
   1533    }
   1534    else {
   1535        // Disable mifare raw timeout, use HCI sw watchdog instead
   1536        phLibNfc_SetMifareRawTimeout(0x00);
   1537        phLibNfc_SetHciTimeout(timeout);
   1538    }
   1539 }
   1540 
   1541 static bool com_android_nfc_NfcManager_doSetTimeout( JNIEnv *e, jobject o,
   1542         jint tech, jint timeout) {
   1543     bool success = false;
   1544     CONCURRENCY_LOCK();
   1545     if (timeout <= 0) {
   1546         ALOGE("Timeout must be positive.");
   1547         return false;
   1548     } else {
   1549         switch (tech) {
   1550             case TARGET_TYPE_MIFARE_CLASSIC:
   1551             case TARGET_TYPE_MIFARE_UL:
   1552                 // Intentional fall-through, Mifare UL, Classic
   1553                 // transceive just uses raw 3A frames
   1554             case TARGET_TYPE_ISO14443_3A:
   1555                 setNfcATimeout(timeout);
   1556                 success = true;
   1557                 break;
   1558             case TARGET_TYPE_ISO14443_4:
   1559                 setIsoDepTimeout(timeout);
   1560                 success = true;
   1561                 break;
   1562             case TARGET_TYPE_FELICA:
   1563                 setFelicaTimeout(timeout);
   1564                 success = true;
   1565                 break;
   1566             default:
   1567                 ALOGW("doSetTimeout: Timeout not supported for tech %d", tech);
   1568                 success = false;
   1569         }
   1570     }
   1571     CONCURRENCY_UNLOCK();
   1572     return success;
   1573 }
   1574 
   1575 static jint com_android_nfc_NfcManager_doGetTimeout( JNIEnv *e, jobject o,
   1576         jint tech) {
   1577     int timeout = -1;
   1578     CONCURRENCY_LOCK();
   1579     switch (tech) {
   1580         case TARGET_TYPE_MIFARE_CLASSIC:
   1581         case TARGET_TYPE_MIFARE_UL:
   1582             // Intentional fall-through, Mifare UL, Classic
   1583             // transceive just uses raw 3A frames
   1584         case TARGET_TYPE_ISO14443_3A:
   1585             timeout = phLibNfc_GetMifareRawTimeout();
   1586             if (timeout == 0) {
   1587                 timeout = phLibNfc_GetHciTimeout();
   1588             } else {
   1589                 // Timeout returned from libnfc needs conversion to ms
   1590                 timeout = (nxp_nfc_timeout_factor * (1 << timeout));
   1591             }
   1592             break;
   1593         case TARGET_TYPE_ISO14443_4:
   1594             timeout = phLibNfc_GetIsoXchgTimeout() & 0x0F; // lower 4 bits only
   1595             if (timeout == 0) {
   1596                 timeout = phLibNfc_GetHciTimeout();
   1597             } else {
   1598                 // Timeout returned from libnfc needs conversion to ms
   1599                 timeout = (nxp_nfc_timeout_factor * (1 << timeout));
   1600             }
   1601             break;
   1602         case TARGET_TYPE_FELICA:
   1603             timeout = phLibNfc_GetFelicaTimeout();
   1604             if (timeout == 0) {
   1605                 timeout = phLibNfc_GetHciTimeout();
   1606             } else {
   1607                 // Felica timeout already in ms
   1608             }
   1609             break;
   1610         default:
   1611             ALOGW("doGetTimeout: Timeout not supported for tech %d", tech);
   1612             break;
   1613     }
   1614     CONCURRENCY_UNLOCK();
   1615     return timeout;
   1616 }
   1617 
   1618 
   1619 static jboolean com_android_nfc_NfcManager_init_native_struc(JNIEnv *e, jobject o)
   1620 {
   1621    NFCSTATUS status;
   1622    struct nfc_jni_native_data *nat = NULL;
   1623    jclass cls;
   1624    jobject obj;
   1625    jfieldID f;
   1626 
   1627    TRACE("******  Init Native Structure ******");
   1628 
   1629    /* Initialize native structure */
   1630    nat = (nfc_jni_native_data*)malloc(sizeof(struct nfc_jni_native_data));
   1631    if(nat == NULL)
   1632    {
   1633       ALOGD("malloc of nfc_jni_native_data failed");
   1634       return FALSE;
   1635    }
   1636    memset(nat, 0, sizeof(*nat));
   1637    e->GetJavaVM(&(nat->vm));
   1638    nat->env_version = e->GetVersion();
   1639    nat->manager = e->NewGlobalRef(o);
   1640 
   1641    cls = e->GetObjectClass(o);
   1642    f = e->GetFieldID(cls, "mNative", "I");
   1643    e->SetIntField(o, f, (jint)nat);
   1644 
   1645    /* Initialize native cached references */
   1646    cached_NfcManager_notifyNdefMessageListeners = e->GetMethodID(cls,
   1647       "notifyNdefMessageListeners","(Lcom/android/nfc/dhimpl/NativeNfcTag;)V");
   1648 
   1649    cached_NfcManager_notifyTransactionListeners = e->GetMethodID(cls,
   1650       "notifyTransactionListeners", "([B)V");
   1651 
   1652    cached_NfcManager_notifyLlcpLinkActivation = e->GetMethodID(cls,
   1653       "notifyLlcpLinkActivation","(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V");
   1654 
   1655    cached_NfcManager_notifyLlcpLinkDeactivated = e->GetMethodID(cls,
   1656       "notifyLlcpLinkDeactivated","(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V");
   1657 
   1658    cached_NfcManager_notifyTargetDeselected = e->GetMethodID(cls,
   1659       "notifyTargetDeselected","()V");
   1660 
   1661    cached_NfcManager_notifySeFieldActivated = e->GetMethodID(cls,
   1662       "notifySeFieldActivated", "()V");
   1663 
   1664    cached_NfcManager_notifySeFieldDeactivated = e->GetMethodID(cls,
   1665       "notifySeFieldDeactivated", "()V");
   1666 
   1667    cached_NfcManager_notifySeApduReceived= e->GetMethodID(cls,
   1668       "notifySeApduReceived", "([B)V");
   1669 
   1670    cached_NfcManager_notifySeMifareAccess = e->GetMethodID(cls,
   1671       "notifySeMifareAccess", "([B)V");
   1672 
   1673    cached_NfcManager_notifySeEmvCardRemoval =  e->GetMethodID(cls,
   1674       "notifySeEmvCardRemoval", "()V");
   1675 
   1676    if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeNfcTag",&(nat->cached_NfcTag)) == -1)
   1677    {
   1678       ALOGD("Native Structure initialization failed");
   1679       return FALSE;
   1680    }
   1681 
   1682    if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeP2pDevice",&(nat->cached_P2pDevice)) == -1)
   1683    {
   1684       ALOGD("Native Structure initialization failed");
   1685       return FALSE;
   1686    }
   1687    TRACE("****** Init Native Structure OK ******");
   1688    return TRUE;
   1689 
   1690 }
   1691 
   1692 /* Init/Deinit method */
   1693 static jboolean com_android_nfc_NfcManager_initialize(JNIEnv *e, jobject o)
   1694 {
   1695    struct nfc_jni_native_data *nat = NULL;
   1696    int init_result = JNI_FALSE;
   1697 #ifdef TNFC_EMULATOR_ONLY
   1698    char value[PROPERTY_VALUE_MAX];
   1699 #endif
   1700    jboolean result;
   1701 
   1702    CONCURRENCY_LOCK();
   1703 
   1704 #ifdef TNFC_EMULATOR_ONLY
   1705    if (!property_get("ro.kernel.qemu", value, 0))
   1706    {
   1707       ALOGE("NFC Initialization failed: not running in an emulator\n");
   1708       goto clean_and_return;
   1709    }
   1710 #endif
   1711 
   1712    /* Retrieve native structure address */
   1713    nat = nfc_jni_get_nat(e, o);
   1714 
   1715    nat->seId = SMX_SECURE_ELEMENT_ID;
   1716 
   1717    nat->lto = 150;  // LLCP_LTO
   1718    nat->miu = 128; // LLCP_MIU
   1719    // WKS indicates well-known services; 1 << sap for each supported SAP.
   1720    // We support Link mgmt (SAP 0), SDP (SAP 1) and SNEP (SAP 4)
   1721    nat->wks = 0x13;  // LLCP_WKS
   1722    nat->opt = 0;  // LLCP_OPT
   1723    nat->p2p_initiator_modes = phNfc_eP2P_ALL;
   1724    nat->p2p_target_modes = 0x0E; // All passive except 106, active
   1725    nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A = TRUE;
   1726    nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B = TRUE;
   1727    nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212 = TRUE;
   1728    nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424 = TRUE;
   1729    nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693 = TRUE;
   1730    nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive = TRUE;
   1731    nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = FALSE;
   1732 
   1733    nat->registry_info.MifareUL = TRUE;
   1734    nat->registry_info.MifareStd = TRUE;
   1735    nat->registry_info.ISO14443_4A = TRUE;
   1736    nat->registry_info.ISO14443_4B = TRUE;
   1737    nat->registry_info.Jewel = TRUE;
   1738    nat->registry_info.Felica = TRUE;
   1739    nat->registry_info.NFC = TRUE;
   1740    nat->registry_info.ISO15693 = TRUE;
   1741 
   1742    exported_nat = nat;
   1743 
   1744    /* Perform the initialization */
   1745    init_result = nfc_jni_initialize(nat);
   1746 
   1747 clean_and_return:
   1748    CONCURRENCY_UNLOCK();
   1749 
   1750    /* Convert the result and return */
   1751    return (init_result==TRUE)?JNI_TRUE:JNI_FALSE;
   1752 }
   1753 
   1754 static jboolean com_android_nfc_NfcManager_deinitialize(JNIEnv *e, jobject o)
   1755 {
   1756    struct timespec ts;
   1757    NFCSTATUS status;
   1758    int result = JNI_FALSE;
   1759    struct nfc_jni_native_data *nat;
   1760    int bStackReset = FALSE;
   1761    struct nfc_jni_callback_data cb_data;
   1762 
   1763    CONCURRENCY_LOCK();
   1764 
   1765    /* Retrieve native structure address */
   1766    nat = nfc_jni_get_nat(e, o);
   1767 
   1768    /* Clear previous configuration */
   1769    memset(&nat->discovery_cfg, 0, sizeof(phLibNfc_sADD_Cfg_t));
   1770    memset(&nat->registry_info, 0, sizeof(phLibNfc_Registry_Info_t));
   1771 
   1772    /* Create the local semaphore */
   1773    if (nfc_cb_data_init(&cb_data, NULL))
   1774    {
   1775       TRACE("phLibNfc_Mgt_DeInitialize()");
   1776       REENTRANCE_LOCK();
   1777       status = phLibNfc_Mgt_DeInitialize(gHWRef, nfc_jni_deinit_callback, (void *)&cb_data);
   1778       REENTRANCE_UNLOCK();
   1779       if (status == NFCSTATUS_PENDING)
   1780       {
   1781          TRACE("phLibNfc_Mgt_DeInitialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
   1782 
   1783          clock_gettime(CLOCK_REALTIME, &ts);
   1784          ts.tv_sec += 5;
   1785 
   1786          /* Wait for callback response */
   1787          if(sem_timedwait(&cb_data.sem, &ts) == -1)
   1788          {
   1789             ALOGW("Operation timed out");
   1790             bStackReset = TRUE;
   1791          }
   1792 
   1793          if(cb_data.status != NFCSTATUS_SUCCESS)
   1794          {
   1795             ALOGE("Failed to deinit the stack");
   1796             bStackReset = TRUE;
   1797          }
   1798       }
   1799       else
   1800       {
   1801          TRACE("phLibNfc_Mgt_DeInitialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
   1802          bStackReset = TRUE;
   1803       }
   1804       nfc_cb_data_deinit(&cb_data);
   1805    }
   1806    else
   1807    {
   1808        ALOGE("Failed to create semaphore (errno=0x%08x)", errno);
   1809        bStackReset = TRUE;
   1810    }
   1811 
   1812    kill_client(nat);
   1813 
   1814    if(bStackReset == TRUE)
   1815    {
   1816       /* Complete deinit. failed, try hard restart of NFC */
   1817       ALOGW("Reseting stack...");
   1818       emergency_recovery(nat);
   1819    }
   1820 
   1821    result = nfc_jni_unconfigure_driver(nat);
   1822 
   1823    TRACE("NFC Deinitialized");
   1824 
   1825    CONCURRENCY_UNLOCK();
   1826 
   1827    return TRUE;
   1828 }
   1829 
   1830 /* Secure Element methods */
   1831 static jintArray com_android_nfc_NfcManager_doGetSecureElementList(JNIEnv *e, jobject o) {
   1832     NFCSTATUS ret;
   1833     jintArray list= NULL;
   1834     phLibNfc_SE_List_t se_list[PHLIBNFC_MAXNO_OF_SE];
   1835     uint8_t i, se_count = PHLIBNFC_MAXNO_OF_SE;
   1836 
   1837     TRACE("******  Get Secure Element List ******");
   1838 
   1839     TRACE("phLibNfc_SE_GetSecureElementList()");
   1840     REENTRANCE_LOCK();
   1841     ret = phLibNfc_SE_GetSecureElementList(se_list, &se_count);
   1842     REENTRANCE_UNLOCK();
   1843     if (ret != NFCSTATUS_SUCCESS) {
   1844         ALOGE("phLibNfc_SE_GetSecureElementList() returned 0x%04x[%s]", ret,
   1845                 nfc_jni_get_status_name(ret));
   1846         return list;
   1847     }
   1848     TRACE("phLibNfc_SE_GetSecureElementList() returned 0x%04x[%s]", ret,
   1849             nfc_jni_get_status_name(ret));
   1850 
   1851     TRACE("Nb SE: %d", se_count);
   1852     list =e->NewIntArray(se_count);
   1853     for (i = 0; i < se_count; i++) {
   1854         if (se_list[i].eSE_Type == phLibNfc_SE_Type_SmartMX) {
   1855             ALOGD("phLibNfc_SE_GetSecureElementList(): SMX detected");
   1856             ALOGD("SE ID #%d: 0x%08x", i, se_list[i].hSecureElement);
   1857         } else if(se_list[i].eSE_Type == phLibNfc_SE_Type_UICC) {
   1858             ALOGD("phLibNfc_SE_GetSecureElementList(): UICC detected");
   1859             ALOGD("SE ID #%d: 0x%08x", i, se_list[i].hSecureElement);
   1860         }
   1861         e->SetIntArrayRegion(list, i, 1, (jint*)&se_list[i].hSecureElement);
   1862     }
   1863 
   1864     e->DeleteLocalRef(list);
   1865 
   1866     return list;
   1867 }
   1868 
   1869 static void com_android_nfc_NfcManager_doSelectSecureElement(JNIEnv *e, jobject o) {
   1870     NFCSTATUS ret;
   1871     struct nfc_jni_native_data *nat;
   1872     struct nfc_jni_callback_data cb_data;
   1873 
   1874     CONCURRENCY_LOCK();
   1875 
   1876     /* Retrieve native structure address */
   1877     nat = nfc_jni_get_nat(e, o);
   1878 
   1879     /* Create the local semaphore */
   1880     if (!nfc_cb_data_init(&cb_data, NULL)) {
   1881         goto clean_and_return;
   1882     }
   1883 
   1884     TRACE("******  Select Secure Element ******");
   1885 
   1886     TRACE("phLibNfc_SE_SetMode()");
   1887     /* Set SE mode - Virtual */
   1888     REENTRANCE_LOCK();
   1889     ret = phLibNfc_SE_SetMode(nat->seId, phLibNfc_SE_ActModeVirtualVolatile, nfc_jni_se_set_mode_callback,
   1890             (void *)&cb_data);
   1891     REENTRANCE_UNLOCK();
   1892     if (ret != NFCSTATUS_PENDING) {
   1893         ALOGD("phLibNfc_SE_SetMode() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   1894         goto clean_and_return;
   1895     }
   1896     TRACE("phLibNfc_SE_SetMode() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   1897 
   1898     /* Wait for callback response */
   1899     if (sem_wait(&cb_data.sem)) {
   1900         ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
   1901         goto clean_and_return;
   1902     }
   1903 
   1904     clean_and_return:
   1905     nfc_cb_data_deinit(&cb_data);
   1906     CONCURRENCY_UNLOCK();
   1907 }
   1908 
   1909 static void com_android_nfc_NfcManager_doDeselectSecureElement(JNIEnv *e, jobject o) {
   1910     NFCSTATUS ret;
   1911     struct nfc_jni_native_data *nat;
   1912     struct nfc_jni_callback_data cb_data;
   1913 
   1914     CONCURRENCY_LOCK();
   1915 
   1916     /* Retrieve native structure address */
   1917     nat = nfc_jni_get_nat(e, o);
   1918 
   1919     /* Create the local semaphore */
   1920     if (!nfc_cb_data_init(&cb_data, NULL)) {
   1921         goto clean_and_return;
   1922     }
   1923 
   1924     TRACE("****** Deselect Secure Element ******");
   1925 
   1926     TRACE("phLibNfc_SE_SetMode()");
   1927     /* Set SE mode - Default */
   1928     REENTRANCE_LOCK();
   1929     ret = phLibNfc_SE_SetMode(nat->seId, phLibNfc_SE_ActModeDefault,
   1930            nfc_jni_se_set_mode_callback, (void *)&cb_data);
   1931     REENTRANCE_UNLOCK();
   1932 
   1933     TRACE("phLibNfc_SE_SetMode returned 0x%02x", ret);
   1934     if (ret != NFCSTATUS_PENDING) {
   1935         ALOGE("phLibNfc_SE_SetMode() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   1936         goto clean_and_return;
   1937     }
   1938     TRACE("phLibNfc_SE_SetMode() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   1939 
   1940     /* Wait for callback response */
   1941     if (sem_wait(&cb_data.sem)) {
   1942         ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
   1943         goto clean_and_return;
   1944     }
   1945 
   1946     clean_and_return:
   1947     nfc_cb_data_deinit(&cb_data);
   1948     CONCURRENCY_UNLOCK();
   1949 }
   1950 
   1951 /* Llcp methods */
   1952 
   1953 static jboolean com_android_nfc_NfcManager_doCheckLlcp(JNIEnv *e, jobject o)
   1954 {
   1955    NFCSTATUS ret;
   1956    bool freeData = false;
   1957    jboolean result = JNI_FALSE;
   1958    struct nfc_jni_native_data *nat;
   1959    struct nfc_jni_callback_data  *cb_data;
   1960 
   1961 
   1962    CONCURRENCY_LOCK();
   1963 
   1964    /* Memory allocation for cb_data
   1965     * This is on the heap because it is used by libnfc
   1966     * even after this call has succesfully finished. It is only freed
   1967     * upon link closure in nfc_jni_llcp_linkStatus_callback.
   1968     */
   1969    cb_data = (struct nfc_jni_callback_data*) malloc (sizeof(nfc_jni_callback_data));
   1970 
   1971    /* Retrieve native structure address */
   1972    nat = nfc_jni_get_nat(e, o);
   1973 
   1974    /* Create the local semaphore */
   1975    if (!nfc_cb_data_init(cb_data, (void*)nat))
   1976    {
   1977       goto clean_and_return;
   1978    }
   1979 
   1980    /* Check LLCP compliancy */
   1981    TRACE("phLibNfc_Llcp_CheckLlcp(hLlcpHandle=0x%08x)", hLlcpHandle);
   1982    REENTRANCE_LOCK();
   1983    ret = phLibNfc_Llcp_CheckLlcp(hLlcpHandle,
   1984                                  nfc_jni_checkLlcp_callback,
   1985                                  nfc_jni_llcp_linkStatus_callback,
   1986                                  (void*)cb_data);
   1987    REENTRANCE_UNLOCK();
   1988    /* In case of a NFCIP return NFCSTATUS_SUCCESS and in case of an another protocol
   1989     * NFCSTATUS_PENDING. In this case NFCSTATUS_SUCCESS will also cause the callback. */
   1990    if(ret != NFCSTATUS_PENDING && ret != NFCSTATUS_SUCCESS)
   1991    {
   1992       ALOGE("phLibNfc_Llcp_CheckLlcp() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   1993       freeData = true;
   1994       goto clean_and_return;
   1995    }
   1996    TRACE("phLibNfc_Llcp_CheckLlcp() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   1997 
   1998    /* Wait for callback response */
   1999    if(sem_wait(&cb_data->sem))
   2000    {
   2001       ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
   2002       goto clean_and_return;
   2003    }
   2004 
   2005    if(cb_data->status == NFCSTATUS_SUCCESS)
   2006    {
   2007       result = JNI_TRUE;
   2008    }
   2009 
   2010 clean_and_return:
   2011    nfc_cb_data_deinit(cb_data);
   2012    if (freeData) {
   2013        free(cb_data);
   2014    }
   2015    CONCURRENCY_UNLOCK();
   2016    return result;
   2017 }
   2018 
   2019 static jboolean com_android_nfc_NfcManager_doActivateLlcp(JNIEnv *e, jobject o)
   2020 {
   2021    NFCSTATUS ret;
   2022    TRACE("phLibNfc_Llcp_Activate(hRemoteDevice=0x%08x)", hLlcpHandle);
   2023    REENTRANCE_LOCK();
   2024    ret = phLibNfc_Llcp_Activate(hLlcpHandle);
   2025    REENTRANCE_UNLOCK();
   2026    if(ret == NFCSTATUS_SUCCESS)
   2027    {
   2028       TRACE("phLibNfc_Llcp_Activate() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   2029       return JNI_TRUE;
   2030    }
   2031    else
   2032    {
   2033       ALOGE("phLibNfc_Llcp_Activate() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   2034       return JNI_FALSE;
   2035    }
   2036 }
   2037 
   2038 
   2039 
   2040 static jobject com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket(JNIEnv *e, jobject o,
   2041         jint nSap, jstring sn)
   2042 {
   2043    NFCSTATUS ret;
   2044    jobject connectionlessSocket = NULL;
   2045    phLibNfc_Handle hLlcpSocket;
   2046    struct nfc_jni_native_data *nat;
   2047    phNfc_sData_t sWorkingBuffer = {NULL, 0};
   2048    phNfc_sData_t serviceName = {NULL, 0};
   2049    phLibNfc_Llcp_sLinkParameters_t sParams;
   2050    jclass clsNativeConnectionlessSocket;
   2051    jfieldID f;
   2052 
   2053    /* Retrieve native structure address */
   2054    nat = nfc_jni_get_nat(e, o);
   2055 
   2056    /* Allocate Working buffer length */
   2057    phLibNfc_Llcp_GetLocalInfo(hLlcpHandle, &sParams);
   2058    sWorkingBuffer.length = sParams.miu + 1; // extra byte for SAP
   2059    sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length);
   2060 
   2061    /* Create socket */
   2062    TRACE("phLibNfc_Llcp_Socket(eType=phFriNfc_LlcpTransport_eConnectionLess, ...)");
   2063    REENTRANCE_LOCK();
   2064    ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionLess,
   2065                               NULL,
   2066                               &sWorkingBuffer,
   2067                               &hLlcpSocket,
   2068                               nfc_jni_llcp_transport_socket_err_callback,
   2069                               (void*)nat);
   2070    REENTRANCE_UNLOCK();
   2071 
   2072    if(ret != NFCSTATUS_SUCCESS)
   2073    {
   2074       lastErrorStatus = ret;
   2075       ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   2076       goto error;
   2077    }
   2078    TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   2079 
   2080    /* Service socket */
   2081    if (sn == NULL) {
   2082        serviceName.buffer = NULL;
   2083        serviceName.length = 0;
   2084    } else {
   2085        serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL);
   2086        serviceName.length = (uint32_t)e->GetStringUTFLength(sn);
   2087    }
   2088 
   2089    /* Bind socket */
   2090    TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap);
   2091    REENTRANCE_LOCK();
   2092    ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, &serviceName);
   2093    REENTRANCE_UNLOCK();
   2094    if(ret != NFCSTATUS_SUCCESS)
   2095    {
   2096       lastErrorStatus = ret;
   2097       ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   2098       /* Close socket created */
   2099       REENTRANCE_LOCK();
   2100       ret = phLibNfc_Llcp_Close(hLlcpSocket);
   2101       REENTRANCE_UNLOCK();
   2102       goto error;
   2103    }
   2104    TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   2105 
   2106 
   2107    /* Create new NativeLlcpConnectionlessSocket object */
   2108    if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpConnectionlessSocket",&(connectionlessSocket)) == -1)
   2109    {
   2110       goto error;
   2111    }
   2112 
   2113    /* Get NativeConnectionless class object */
   2114    clsNativeConnectionlessSocket = e->GetObjectClass(connectionlessSocket);
   2115    if(e->ExceptionCheck())
   2116    {
   2117       goto error;
   2118    }
   2119 
   2120    /* Set socket handle */
   2121    f = e->GetFieldID(clsNativeConnectionlessSocket, "mHandle", "I");
   2122    e->SetIntField(connectionlessSocket, f,(jint)hLlcpSocket);
   2123    TRACE("Connectionless socket Handle = %02x\n",hLlcpSocket);
   2124 
   2125    /* Set the miu link of the connectionless socket */
   2126    f = e->GetFieldID(clsNativeConnectionlessSocket, "mLinkMiu", "I");
   2127    e->SetIntField(connectionlessSocket, f,(jint)PHFRINFC_LLCP_MIU_DEFAULT);
   2128    TRACE("Connectionless socket Link MIU = %d\n",PHFRINFC_LLCP_MIU_DEFAULT);
   2129 
   2130    /* Set socket SAP */
   2131    f = e->GetFieldID(clsNativeConnectionlessSocket, "mSap", "I");
   2132    e->SetIntField(connectionlessSocket, f,(jint)nSap);
   2133    TRACE("Connectionless socket SAP = %d\n",nSap);
   2134 
   2135    return connectionlessSocket;
   2136 error:
   2137    if (serviceName.buffer != NULL) {
   2138       e->ReleaseStringUTFChars(sn, (const char *)serviceName.buffer);
   2139    }
   2140 
   2141    if (sWorkingBuffer.buffer != NULL) {
   2142        free(sWorkingBuffer.buffer);
   2143    }
   2144 
   2145    return NULL;
   2146 }
   2147 
   2148 static jobject com_android_nfc_NfcManager_doCreateLlcpServiceSocket(JNIEnv *e, jobject o, jint nSap, jstring sn, jint miu, jint rw, jint linearBufferLength)
   2149 {
   2150    NFCSTATUS ret;
   2151    phLibNfc_Handle hLlcpSocket;
   2152    phLibNfc_Llcp_sSocketOptions_t sOptions;
   2153    phNfc_sData_t sWorkingBuffer;
   2154    phNfc_sData_t serviceName;
   2155    struct nfc_jni_native_data *nat;
   2156    jobject serviceSocket = NULL;
   2157    jclass clsNativeLlcpServiceSocket;
   2158    jfieldID f;
   2159 
   2160    /* Retrieve native structure address */
   2161    nat = nfc_jni_get_nat(e, o);
   2162 
   2163    /* Set Connection Oriented socket options */
   2164    sOptions.miu = miu;
   2165    sOptions.rw  = rw;
   2166 
   2167    /* Allocate Working buffer length */
   2168    sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength;
   2169    sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length);
   2170 
   2171 
   2172    /* Create socket */
   2173    TRACE("phLibNfc_Llcp_Socket(hRemoteDevice=0x%08x, eType=phFriNfc_LlcpTransport_eConnectionOriented, ...)", hLlcpHandle);
   2174    REENTRANCE_LOCK();
   2175    ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionOriented,
   2176                               &sOptions,
   2177                               &sWorkingBuffer,
   2178                               &hLlcpSocket,
   2179                               nfc_jni_llcp_transport_socket_err_callback,
   2180                               (void*)nat);
   2181    REENTRANCE_UNLOCK();
   2182 
   2183    if(ret != NFCSTATUS_SUCCESS)
   2184    {
   2185       ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   2186       lastErrorStatus = ret;
   2187       goto error;
   2188    }
   2189    TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   2190 
   2191    /* Service socket */
   2192    if (sn == NULL) {
   2193        serviceName.buffer = NULL;
   2194        serviceName.length = 0;
   2195    } else {
   2196        serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL);
   2197        serviceName.length = (uint32_t)e->GetStringUTFLength(sn);
   2198    }
   2199 
   2200    /* Bind socket */
   2201    TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap);
   2202    REENTRANCE_LOCK();
   2203    ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, &serviceName);
   2204    REENTRANCE_UNLOCK();
   2205    if(ret != NFCSTATUS_SUCCESS)
   2206    {
   2207       lastErrorStatus = ret;
   2208       ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   2209       /* Close socket created */
   2210       ret = phLibNfc_Llcp_Close(hLlcpSocket);
   2211       goto error;
   2212    }
   2213    TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   2214 
   2215    TRACE("phLibNfc_Llcp_Listen(hSocket=0x%08x, ...)", hLlcpSocket);
   2216    REENTRANCE_LOCK();
   2217    ret = phLibNfc_Llcp_Listen( hLlcpSocket,
   2218                                nfc_jni_llcp_transport_listen_socket_callback,
   2219                                (void*)hLlcpSocket);
   2220    REENTRANCE_UNLOCK();
   2221 
   2222    if(ret != NFCSTATUS_SUCCESS)
   2223    {
   2224       ALOGE("phLibNfc_Llcp_Listen() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   2225       lastErrorStatus = ret;
   2226       /* Close created socket */
   2227       REENTRANCE_LOCK();
   2228       ret = phLibNfc_Llcp_Close(hLlcpSocket);
   2229       REENTRANCE_UNLOCK();
   2230       goto error;
   2231    }
   2232    TRACE("phLibNfc_Llcp_Listen() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   2233 
   2234    /* Create new NativeLlcpServiceSocket object */
   2235    if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpServiceSocket",&(serviceSocket)) == -1)
   2236    {
   2237       ALOGE("Llcp Socket object creation error");
   2238       goto error;
   2239    }
   2240 
   2241    /* Get NativeLlcpServiceSocket class object */
   2242    clsNativeLlcpServiceSocket = e->GetObjectClass(serviceSocket);
   2243    if(e->ExceptionCheck())
   2244    {
   2245       ALOGE("Llcp Socket get object class error");
   2246       goto error;
   2247    }
   2248 
   2249    /* Set socket handle */
   2250    f = e->GetFieldID(clsNativeLlcpServiceSocket, "mHandle", "I");
   2251    e->SetIntField(serviceSocket, f,(jint)hLlcpSocket);
   2252    TRACE("Service socket Handle = %02x\n",hLlcpSocket);
   2253 
   2254    /* Set socket linear buffer length */
   2255    f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalLinearBufferLength", "I");
   2256    e->SetIntField(serviceSocket, f,(jint)linearBufferLength);
   2257    TRACE("Service socket Linear buffer length = %02x\n",linearBufferLength);
   2258 
   2259    /* Set socket MIU */
   2260    f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalMiu", "I");
   2261    e->SetIntField(serviceSocket, f,(jint)miu);
   2262    TRACE("Service socket MIU = %d\n",miu);
   2263 
   2264    /* Set socket RW */
   2265    f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalRw", "I");
   2266    e->SetIntField(serviceSocket, f,(jint)rw);
   2267    TRACE("Service socket RW = %d\n",rw);
   2268 
   2269    return serviceSocket;
   2270 error:
   2271    if (serviceName.buffer != NULL) {
   2272       e->ReleaseStringUTFChars(sn, (const char *)serviceName.buffer);
   2273    }
   2274    return NULL;
   2275 }
   2276 
   2277 static jobject com_android_nfc_NfcManager_doCreateLlcpSocket(JNIEnv *e, jobject o, jint nSap, jint miu, jint rw, jint linearBufferLength)
   2278 {
   2279    jobject clientSocket = NULL;
   2280    NFCSTATUS ret;
   2281    phLibNfc_Handle hLlcpSocket;
   2282    phLibNfc_Llcp_sSocketOptions_t sOptions;
   2283    phNfc_sData_t sWorkingBuffer;
   2284    struct nfc_jni_native_data *nat;
   2285    jclass clsNativeLlcpSocket;
   2286    jfieldID f;
   2287 
   2288    /* Retrieve native structure address */
   2289    nat = nfc_jni_get_nat(e, o);
   2290 
   2291    /* Set Connection Oriented socket options */
   2292    sOptions.miu = miu;
   2293    sOptions.rw  = rw;
   2294 
   2295    /* Allocate Working buffer length */
   2296    sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength;
   2297    sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length);
   2298 
   2299    /* Create socket */
   2300    TRACE("phLibNfc_Llcp_Socket(eType=phFriNfc_LlcpTransport_eConnectionOriented, ...)");
   2301    REENTRANCE_LOCK();
   2302    ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionOriented,
   2303                               &sOptions,
   2304                               &sWorkingBuffer,
   2305                               &hLlcpSocket,
   2306                               nfc_jni_llcp_transport_socket_err_callback,
   2307                               (void*)nat);
   2308    REENTRANCE_UNLOCK();
   2309 
   2310    if(ret != NFCSTATUS_SUCCESS)
   2311    {
   2312       ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   2313       lastErrorStatus = ret;
   2314       return NULL;
   2315    }
   2316    TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   2317 
   2318    /* Create new NativeLlcpSocket object */
   2319    if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpSocket",&(clientSocket)) == -1)
   2320    {
   2321       ALOGE("Llcp socket object creation error");
   2322       return NULL;
   2323    }
   2324 
   2325    /* Get NativeConnectionless class object */
   2326    clsNativeLlcpSocket = e->GetObjectClass(clientSocket);
   2327    if(e->ExceptionCheck())
   2328    {
   2329       ALOGE("Get class object error");
   2330       return NULL;
   2331    }
   2332 
   2333    /* Test if an SAP number is present */
   2334    if(nSap != 0)
   2335    {
   2336       /* Bind socket */
   2337       TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap);
   2338       REENTRANCE_LOCK();
   2339       ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, NULL);
   2340       REENTRANCE_UNLOCK();
   2341       if(ret != NFCSTATUS_SUCCESS)
   2342       {
   2343          lastErrorStatus = ret;
   2344          ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   2345          /* Close socket created */
   2346          REENTRANCE_LOCK();
   2347          ret = phLibNfc_Llcp_Close(hLlcpSocket);
   2348          REENTRANCE_UNLOCK();
   2349          return NULL;
   2350       }
   2351       TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   2352 
   2353       /* Set socket SAP */
   2354       f = e->GetFieldID(clsNativeLlcpSocket, "mSap", "I");
   2355       e->SetIntField(clientSocket, f,(jint)nSap);
   2356       TRACE("socket SAP = %d\n",nSap);
   2357    }
   2358 
   2359    /* Set socket handle */
   2360    f = e->GetFieldID(clsNativeLlcpSocket, "mHandle", "I");
   2361    e->SetIntField(clientSocket, f,(jint)hLlcpSocket);
   2362    TRACE("socket Handle = %02x\n",hLlcpSocket);
   2363 
   2364    /* Set socket MIU */
   2365    f = e->GetFieldID(clsNativeLlcpSocket, "mLocalMiu", "I");
   2366    e->SetIntField(clientSocket, f,(jint)miu);
   2367    TRACE("socket MIU = %d\n",miu);
   2368 
   2369    /* Set socket RW */
   2370    f = e->GetFieldID(clsNativeLlcpSocket, "mLocalRw", "I");
   2371    e->SetIntField(clientSocket, f,(jint)rw);
   2372    TRACE("socket RW = %d\n",rw);
   2373 
   2374 
   2375    return clientSocket;
   2376 }
   2377 
   2378 static jint com_android_nfc_NfcManager_doGetLastError(JNIEnv *e, jobject o)
   2379 {
   2380    TRACE("Last Error Status = 0x%02x",lastErrorStatus);
   2381 
   2382    if(lastErrorStatus == NFCSTATUS_BUFFER_TOO_SMALL)
   2383    {
   2384       return ERROR_BUFFER_TOO_SMALL;
   2385    }
   2386    else if(lastErrorStatus == NFCSTATUS_INSUFFICIENT_RESOURCES)
   2387    {
   2388       return  ERROR_INSUFFICIENT_RESOURCES;
   2389    }
   2390    else
   2391    {
   2392       return lastErrorStatus;
   2393    }
   2394 }
   2395 
   2396 static void com_android_nfc_NfcManager_doAbort(JNIEnv *e, jobject o)
   2397 {
   2398     emergency_recovery(NULL);
   2399 }
   2400 
   2401 static void com_android_nfc_NfcManager_doSetP2pInitiatorModes(JNIEnv *e, jobject o,
   2402         jint modes)
   2403 {
   2404     ALOGE("Setting init modes to %x", modes);
   2405     struct nfc_jni_native_data *nat = NULL;
   2406     nat = nfc_jni_get_nat(e, o);
   2407     nat->p2p_initiator_modes = modes;
   2408 }
   2409 
   2410 static void com_android_nfc_NfcManager_doSetP2pTargetModes(JNIEnv *e, jobject o,
   2411         jint modes)
   2412 {
   2413     ALOGE("Setting target modes to %x", modes);
   2414     struct nfc_jni_native_data *nat = NULL;
   2415     nat = nfc_jni_get_nat(e, o);
   2416     nat->p2p_target_modes = modes;
   2417 }
   2418 
   2419 static bool performDownload(struct nfc_jni_native_data* nat, bool takeLock) {
   2420     bool result = FALSE;
   2421     int load_result;
   2422     bool wasDisabled = FALSE;
   2423     uint8_t OutputBuffer[1];
   2424     uint8_t InputBuffer[1];
   2425     NFCSTATUS status = NFCSTATUS_FAILED;
   2426     struct nfc_jni_callback_data cb_data;
   2427 
   2428     /* Create the local semaphore */
   2429     if (!nfc_cb_data_init(&cb_data, NULL))
   2430     {
   2431        result = FALSE;
   2432        goto clean_and_return;
   2433     }
   2434 
   2435     if (takeLock)
   2436     {
   2437         CONCURRENCY_LOCK();
   2438     }
   2439 
   2440     /* Initialize Driver */
   2441     if(!driverConfigured)
   2442     {
   2443         result = nfc_jni_configure_driver(nat);
   2444         wasDisabled = TRUE;
   2445     }
   2446     TRACE("com_android_nfc_NfcManager_doDownload()");
   2447 
   2448     TRACE("Go in Download Mode");
   2449     phLibNfc_Download_Mode();
   2450 
   2451     TRACE("Load new Firmware Image");
   2452     load_result = phLibNfc_Load_Firmware_Image();
   2453     if(load_result != 0)
   2454     {
   2455         TRACE("Load new Firmware Image - status = %d",load_result);
   2456         result = FALSE;
   2457         goto clean_and_return;
   2458     }
   2459 
   2460     // Download
   2461     gInputParam.buffer  = InputBuffer;
   2462     gInputParam.length  = 0x01;
   2463     gOutputParam.buffer = OutputBuffer;
   2464     gOutputParam.length = 0x01;
   2465 
   2466     ALOGD("Download new Firmware");
   2467     REENTRANCE_LOCK();
   2468     status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_FW_DOWNLOAD, &gInputParam, &gOutputParam, nfc_jni_ioctl_callback, (void *)&cb_data);
   2469     REENTRANCE_UNLOCK();
   2470     if(status != NFCSTATUS_PENDING)
   2471     {
   2472         ALOGE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
   2473         result = FALSE;
   2474         goto clean_and_return;
   2475     }
   2476     TRACE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
   2477 
   2478     /* Wait for callback response */
   2479     if(sem_wait(&cb_data.sem))
   2480     {
   2481        ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
   2482        result = FALSE;
   2483        goto clean_and_return;
   2484     }
   2485 
   2486     /* NOTE: we will get NFCSTATUS_FEATURE_NOT_SUPPORTED when we
   2487        try to download an old-style firmware on top of a new-style
   2488        firmware.  Hence, this is expected behavior, and not an
   2489        error condition. */
   2490     if(cb_data.status != NFCSTATUS_SUCCESS && cb_data.status != NFCSTATUS_FEATURE_NOT_SUPPORTED)
   2491     {
   2492         TRACE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
   2493         result = FALSE;
   2494         goto clean_and_return;
   2495     }
   2496 
   2497     if(cb_data.status == NFCSTATUS_FEATURE_NOT_SUPPORTED)
   2498     {
   2499         ALOGW("Old-style firmware not installed on top of new-style firmware. Using existing firmware in the chip.");
   2500     }
   2501 
   2502     /*Download is successful*/
   2503     result = TRUE;
   2504 clean_and_return:
   2505     TRACE("phLibNfc_HW_Reset()");
   2506     phLibNfc_HW_Reset();
   2507     /* Deinitialize Driver */
   2508     if(wasDisabled)
   2509     {
   2510         result = nfc_jni_unconfigure_driver(nat);
   2511     }
   2512     if (takeLock)
   2513     {
   2514         CONCURRENCY_UNLOCK();
   2515     }
   2516     nfc_cb_data_deinit(&cb_data);
   2517     return result;
   2518 }
   2519 
   2520 static jboolean com_android_nfc_NfcManager_doDownload(JNIEnv *e, jobject o)
   2521 {
   2522     struct nfc_jni_native_data *nat = NULL;
   2523     nat = nfc_jni_get_nat(e, o);
   2524     return performDownload(nat, true);
   2525 }
   2526 
   2527 static jstring com_android_nfc_NfcManager_doDump(JNIEnv *e, jobject o)
   2528 {
   2529     char buffer[100];
   2530     snprintf(buffer, sizeof(buffer), "libnfc llc error_count=%u", libnfc_llc_error_count);
   2531     return e->NewStringUTF(buffer);
   2532 }
   2533 
   2534 /*
   2535  * JNI registration.
   2536  */
   2537 static JNINativeMethod gMethods[] =
   2538 {
   2539    {"doDownload", "()Z",
   2540         (void *)com_android_nfc_NfcManager_doDownload},
   2541 
   2542    {"initializeNativeStructure", "()Z",
   2543       (void *)com_android_nfc_NfcManager_init_native_struc},
   2544 
   2545    {"doInitialize", "()Z",
   2546       (void *)com_android_nfc_NfcManager_initialize},
   2547 
   2548    {"doDeinitialize", "()Z",
   2549       (void *)com_android_nfc_NfcManager_deinitialize},
   2550 
   2551    {"enableDiscovery", "()V",
   2552       (void *)com_android_nfc_NfcManager_enableDiscovery},
   2553 
   2554    {"doGetSecureElementList", "()[I",
   2555       (void *)com_android_nfc_NfcManager_doGetSecureElementList},
   2556 
   2557    {"doSelectSecureElement", "()V",
   2558       (void *)com_android_nfc_NfcManager_doSelectSecureElement},
   2559 
   2560    {"doDeselectSecureElement", "()V",
   2561       (void *)com_android_nfc_NfcManager_doDeselectSecureElement},
   2562 
   2563    {"doCheckLlcp", "()Z",
   2564       (void *)com_android_nfc_NfcManager_doCheckLlcp},
   2565 
   2566    {"doActivateLlcp", "()Z",
   2567       (void *)com_android_nfc_NfcManager_doActivateLlcp},
   2568 
   2569    {"doCreateLlcpConnectionlessSocket", "(ILjava/lang/String;)Lcom/android/nfc/dhimpl/NativeLlcpConnectionlessSocket;",
   2570       (void *)com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket},
   2571 
   2572    {"doCreateLlcpServiceSocket", "(ILjava/lang/String;III)Lcom/android/nfc/dhimpl/NativeLlcpServiceSocket;",
   2573       (void *)com_android_nfc_NfcManager_doCreateLlcpServiceSocket},
   2574 
   2575    {"doCreateLlcpSocket", "(IIII)Lcom/android/nfc/dhimpl/NativeLlcpSocket;",
   2576       (void *)com_android_nfc_NfcManager_doCreateLlcpSocket},
   2577 
   2578    {"doGetLastError", "()I",
   2579       (void *)com_android_nfc_NfcManager_doGetLastError},
   2580 
   2581    {"disableDiscovery", "()V",
   2582       (void *)com_android_nfc_NfcManager_disableDiscovery},
   2583 
   2584    {"doSetTimeout", "(II)Z",
   2585       (void *)com_android_nfc_NfcManager_doSetTimeout},
   2586 
   2587    {"doGetTimeout", "(I)I",
   2588       (void *)com_android_nfc_NfcManager_doGetTimeout},
   2589 
   2590    {"doResetTimeouts", "()V",
   2591       (void *)com_android_nfc_NfcManager_doResetTimeouts},
   2592 
   2593    {"doAbort", "()V",
   2594       (void *)com_android_nfc_NfcManager_doAbort},
   2595 
   2596    {"doSetP2pInitiatorModes","(I)V",
   2597       (void *)com_android_nfc_NfcManager_doSetP2pInitiatorModes},
   2598 
   2599    {"doSetP2pTargetModes","(I)V",
   2600       (void *)com_android_nfc_NfcManager_doSetP2pTargetModes},
   2601 
   2602    {"doDump", "()Ljava/lang/String;",
   2603       (void *)com_android_nfc_NfcManager_doDump},
   2604 };
   2605 
   2606 
   2607 int register_com_android_nfc_NativeNfcManager(JNIEnv *e)
   2608 {
   2609     nfc_jni_native_monitor_t *nfc_jni_native_monitor;
   2610 
   2611    nfc_jni_native_monitor = nfc_jni_init_monitor();
   2612    if(nfc_jni_native_monitor == NULL)
   2613    {
   2614       ALOGE("NFC Manager cannot recover native monitor %x\n", errno);
   2615       return -1;
   2616    }
   2617 
   2618    return jniRegisterNativeMethods(e,
   2619       "com/android/nfc/dhimpl/NativeNfcManager",
   2620       gMethods, NELEM(gMethods));
   2621 }
   2622 
   2623 } /* namespace android */
   2624