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