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