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 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         if (reader_mode)
   1397         {
   1398             nat->p2p_initiator_modes = 0;
   1399             nat->p2p_target_modes = 0;
   1400             nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = TRUE;
   1401             nat->discovery_cfg.Duration = 200000; /* in ms */
   1402         }
   1403         else
   1404         {
   1405             nat->p2p_initiator_modes = phNfc_eP2P_ALL;
   1406             nat->p2p_target_modes = 0x0E; // All passive except 106, active
   1407             nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = FALSE;
   1408             nat->discovery_cfg.Duration = 300000; /* in ms */
   1409         }
   1410         nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A = (modes & 0x01) != 0;
   1411         nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B = (modes & 0x02) != 0;
   1412         nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212 = (modes & 0x04) != 0;
   1413         nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424 = (modes & 0x04) != 0;
   1414         nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693 = (modes & 0x08) != 0;
   1415     }
   1416 
   1417     nfc_jni_start_discovery_locked(nat, restart);
   1418 clean_and_return:
   1419     CONCURRENCY_UNLOCK();
   1420 }
   1421 
   1422 static void com_android_nfc_NfcManager_doResetTimeouts(JNIEnv*, jobject) {
   1423     CONCURRENCY_LOCK();
   1424     nfc_jni_reset_timeout_values();
   1425     CONCURRENCY_UNLOCK();
   1426 }
   1427 
   1428 static void setFelicaTimeout(jint timeout) {
   1429    // The Felica timeout is configurable in the PN544 upto a maximum of 255 ms.
   1430    // It can be set to 0 to disable the timeout altogether, in which case we
   1431    // use the sw watchdog as a fallback.
   1432    if (timeout <= 255) {
   1433        phLibNfc_SetFelicaTimeout(timeout);
   1434    } else {
   1435        // Disable hw timeout, use sw watchdog for timeout
   1436        phLibNfc_SetFelicaTimeout(0);
   1437        phLibNfc_SetHciTimeout(timeout);
   1438    }
   1439 
   1440 }
   1441 // Calculates ceiling log2 of value
   1442 static unsigned int log2(int value) {
   1443     unsigned int ret = 0;
   1444     bool isPowerOf2 = ((value & (value - 1)) == 0);
   1445     while ( (value >> ret) > 1 ) ret++;
   1446     if (!isPowerOf2) ret++;
   1447     return ret;
   1448 }
   1449 
   1450 // The Iso/Mifare Xchg timeout in PN544 is a non-linear function over X
   1451 // spanning 0 - 4.9s: timeout in seconds = (256 * 16 / 13560000) * 2 ^ X
   1452 //
   1453 // We keep the constant part of the formula in a static; note the factor
   1454 // 1000 off, which is due to the fact that the formula calculates seconds,
   1455 // but this method gets milliseconds as an argument.
   1456 static double nxp_nfc_timeout_factor = (256 * 16) / 13560.0;
   1457 
   1458 static int calcTimeout(int timeout_in_ms) {
   1459    // timeout = (256 * 16 / 13560000) * 2 ^ X
   1460    // First find the first X for which timeout > requested timeout
   1461    return (log2(ceil(((double) timeout_in_ms) / nxp_nfc_timeout_factor)));
   1462 }
   1463 
   1464 static void setIsoDepTimeout(jint timeout) {
   1465    if (timeout <= 4900) {
   1466        int value = calcTimeout(timeout);
   1467        // Then re-compute the actual timeout based on X
   1468        double actual_timeout = nxp_nfc_timeout_factor * (1 << value);
   1469        // Set the sw watchdog a bit longer (The PN544 timeout is very accurate,
   1470        // but it will take some time to get back through the sw layers.
   1471        // 500 ms should be enough).
   1472        phLibNfc_SetHciTimeout(ceil(actual_timeout + 500));
   1473        value |= 0x10; // bit 4 to enable timeout
   1474        phLibNfc_SetIsoXchgTimeout(value);
   1475    }
   1476    else {
   1477        // Also note that if we desire a timeout > 4.9s, the Iso Xchg timeout
   1478        // must be disabled completely, to prevent the PN544 from aborting
   1479        // the transaction. We reuse the HCI sw watchdog to catch the timeout
   1480        // in that case.
   1481        phLibNfc_SetIsoXchgTimeout(0x00);
   1482        phLibNfc_SetHciTimeout(timeout);
   1483    }
   1484 }
   1485 
   1486 static void setNfcATimeout(jint timeout) {
   1487    if (timeout <= 4900) {
   1488        int value = calcTimeout(timeout);
   1489        phLibNfc_SetMifareRawTimeout(value);
   1490    }
   1491    else {
   1492        // Disable mifare raw timeout, use HCI sw watchdog instead
   1493        phLibNfc_SetMifareRawTimeout(0x00);
   1494        phLibNfc_SetHciTimeout(timeout);
   1495    }
   1496 }
   1497 
   1498 static bool com_android_nfc_NfcManager_doSetTimeout(JNIEnv*, jobject,
   1499         jint tech, jint timeout) {
   1500     bool success = false;
   1501     CONCURRENCY_LOCK();
   1502     if (timeout <= 0) {
   1503         ALOGE("Timeout must be positive.");
   1504         success = false;
   1505     } else {
   1506         switch (tech) {
   1507             case TARGET_TYPE_MIFARE_CLASSIC:
   1508             case TARGET_TYPE_MIFARE_UL:
   1509                 // Intentional fall-through, Mifare UL, Classic
   1510                 // transceive just uses raw 3A frames
   1511             case TARGET_TYPE_ISO14443_3A:
   1512                 setNfcATimeout(timeout);
   1513                 success = true;
   1514                 break;
   1515             case TARGET_TYPE_ISO14443_4:
   1516                 setIsoDepTimeout(timeout);
   1517                 success = true;
   1518                 break;
   1519             case TARGET_TYPE_FELICA:
   1520                 setFelicaTimeout(timeout);
   1521                 success = true;
   1522                 break;
   1523             default:
   1524                 ALOGW("doSetTimeout: Timeout not supported for tech %d", tech);
   1525                 success = false;
   1526         }
   1527     }
   1528     CONCURRENCY_UNLOCK();
   1529     return success;
   1530 }
   1531 
   1532 static jint com_android_nfc_NfcManager_doGetTimeout(JNIEnv*, jobject,
   1533         jint tech) {
   1534     int timeout = -1;
   1535     CONCURRENCY_LOCK();
   1536     switch (tech) {
   1537         case TARGET_TYPE_MIFARE_CLASSIC:
   1538         case TARGET_TYPE_MIFARE_UL:
   1539             // Intentional fall-through, Mifare UL, Classic
   1540             // transceive just uses raw 3A frames
   1541         case TARGET_TYPE_ISO14443_3A:
   1542             timeout = phLibNfc_GetMifareRawTimeout();
   1543             if (timeout == 0) {
   1544                 timeout = phLibNfc_GetHciTimeout();
   1545             } else {
   1546                 // Timeout returned from libnfc needs conversion to ms
   1547                 timeout = (nxp_nfc_timeout_factor * (1 << timeout));
   1548             }
   1549             break;
   1550         case TARGET_TYPE_ISO14443_4:
   1551             timeout = phLibNfc_GetIsoXchgTimeout() & 0x0F; // lower 4 bits only
   1552             if (timeout == 0) {
   1553                 timeout = phLibNfc_GetHciTimeout();
   1554             } else {
   1555                 // Timeout returned from libnfc needs conversion to ms
   1556                 timeout = (nxp_nfc_timeout_factor * (1 << timeout));
   1557             }
   1558             break;
   1559         case TARGET_TYPE_FELICA:
   1560             timeout = phLibNfc_GetFelicaTimeout();
   1561             if (timeout == 0) {
   1562                 timeout = phLibNfc_GetHciTimeout();
   1563             } else {
   1564                 // Felica timeout already in ms
   1565             }
   1566             break;
   1567         default:
   1568             ALOGW("doGetTimeout: Timeout not supported for tech %d", tech);
   1569             break;
   1570     }
   1571     CONCURRENCY_UNLOCK();
   1572     return timeout;
   1573 }
   1574 
   1575 
   1576 static jboolean com_android_nfc_NfcManager_init_native_struc(JNIEnv *e, jobject o)
   1577 {
   1578    NFCSTATUS status;
   1579    struct nfc_jni_native_data *nat = NULL;
   1580    jclass cls;
   1581    jobject obj;
   1582    jfieldID f;
   1583 
   1584    TRACE("******  Init Native Structure ******");
   1585 
   1586    /* Initialize native structure */
   1587    nat = (nfc_jni_native_data*)malloc(sizeof(struct nfc_jni_native_data));
   1588    if(nat == NULL)
   1589    {
   1590       ALOGD("malloc of nfc_jni_native_data failed");
   1591       return FALSE;
   1592    }
   1593    memset(nat, 0, sizeof(*nat));
   1594    e->GetJavaVM(&(nat->vm));
   1595    nat->env_version = e->GetVersion();
   1596    nat->manager = e->NewGlobalRef(o);
   1597 
   1598    cls = e->GetObjectClass(o);
   1599    f = e->GetFieldID(cls, "mNative", "J");
   1600    e->SetLongField(o, f, (jlong)nat);
   1601 
   1602    /* Initialize native cached references */
   1603    cached_NfcManager_notifyNdefMessageListeners = e->GetMethodID(cls,
   1604       "notifyNdefMessageListeners","(Lcom/android/nfc/dhimpl/NativeNfcTag;)V");
   1605 
   1606    cached_NfcManager_notifyLlcpLinkActivation = e->GetMethodID(cls,
   1607       "notifyLlcpLinkActivation","(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V");
   1608 
   1609    cached_NfcManager_notifyLlcpLinkDeactivated = e->GetMethodID(cls,
   1610       "notifyLlcpLinkDeactivated","(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V");
   1611 
   1612    cached_NfcManager_notifyRfFieldActivated = e->GetMethodID(cls,
   1613       "notifyRfFieldActivated", "()V");
   1614 
   1615    cached_NfcManager_notifyRfFieldDeactivated = e->GetMethodID(cls,
   1616       "notifyRfFieldDeactivated", "()V");
   1617 
   1618    if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeNfcTag",&(nat->cached_NfcTag)) == -1)
   1619    {
   1620       ALOGD("Native Structure initialization failed");
   1621       return FALSE;
   1622    }
   1623 
   1624    if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeP2pDevice",&(nat->cached_P2pDevice)) == -1)
   1625    {
   1626       ALOGD("Native Structure initialization failed");
   1627       return FALSE;
   1628    }
   1629    TRACE("****** Init Native Structure OK ******");
   1630    return TRUE;
   1631 
   1632 }
   1633 
   1634 /* Init/Deinit method */
   1635 static jboolean com_android_nfc_NfcManager_initialize(JNIEnv *e, jobject o)
   1636 {
   1637    struct nfc_jni_native_data *nat = NULL;
   1638    int init_result = JNI_FALSE;
   1639 #ifdef TNFC_EMULATOR_ONLY
   1640    char value[PROPERTY_VALUE_MAX];
   1641 #endif
   1642    jboolean result;
   1643 
   1644    CONCURRENCY_LOCK();
   1645 
   1646 #ifdef TNFC_EMULATOR_ONLY
   1647    if (!property_get("ro.kernel.qemu", value, 0))
   1648    {
   1649       ALOGE("NFC Initialization failed: not running in an emulator\n");
   1650       goto clean_and_return;
   1651    }
   1652 #endif
   1653 
   1654    /* Retrieve native structure address */
   1655    nat = nfc_jni_get_nat(e, o);
   1656 
   1657    nat->seId = SMX_SECURE_ELEMENT_ID;
   1658 
   1659    nat->lto = 150;  // LLCP_LTO
   1660    nat->miu = 128; // LLCP_MIU
   1661    // WKS indicates well-known services; 1 << sap for each supported SAP.
   1662    // We support Link mgmt (SAP 0), SDP (SAP 1) and SNEP (SAP 4)
   1663    nat->wks = 0x13;  // LLCP_WKS
   1664    nat->opt = 0;  // LLCP_OPT
   1665    nat->p2p_initiator_modes = phNfc_eP2P_ALL;
   1666    nat->p2p_target_modes = 0x0E; // All passive except 106, active
   1667    nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A = TRUE;
   1668    nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B = TRUE;
   1669    nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212 = TRUE;
   1670    nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424 = TRUE;
   1671    nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693 = TRUE;
   1672    nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive = TRUE;
   1673    nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = FALSE;
   1674 
   1675    nat->registry_info.MifareUL = TRUE;
   1676    nat->registry_info.MifareStd = TRUE;
   1677    nat->registry_info.ISO14443_4A = TRUE;
   1678    nat->registry_info.ISO14443_4B = TRUE;
   1679    nat->registry_info.Jewel = TRUE;
   1680    nat->registry_info.Felica = TRUE;
   1681    nat->registry_info.NFC = TRUE;
   1682    nat->registry_info.ISO15693 = TRUE;
   1683 
   1684    exported_nat = nat;
   1685 
   1686    /* Perform the initialization */
   1687    init_result = nfc_jni_initialize(nat);
   1688 
   1689 clean_and_return:
   1690    CONCURRENCY_UNLOCK();
   1691 
   1692    /* Convert the result and return */
   1693    return (init_result==TRUE)?JNI_TRUE:JNI_FALSE;
   1694 }
   1695 
   1696 static jboolean com_android_nfc_NfcManager_deinitialize(JNIEnv *e, jobject o)
   1697 {
   1698    struct timespec ts;
   1699    NFCSTATUS status;
   1700    int result = JNI_FALSE;
   1701    struct nfc_jni_native_data *nat;
   1702    int bStackReset = FALSE;
   1703    struct nfc_jni_callback_data cb_data;
   1704 
   1705    CONCURRENCY_LOCK();
   1706 
   1707    /* Retrieve native structure address */
   1708    nat = nfc_jni_get_nat(e, o);
   1709 
   1710    /* Clear previous configuration */
   1711    memset(&nat->discovery_cfg, 0, sizeof(phLibNfc_sADD_Cfg_t));
   1712    memset(&nat->registry_info, 0, sizeof(phLibNfc_Registry_Info_t));
   1713 
   1714    /* Create the local semaphore */
   1715    if (nfc_cb_data_init(&cb_data, NULL))
   1716    {
   1717       TRACE("phLibNfc_Mgt_DeInitialize()");
   1718       REENTRANCE_LOCK();
   1719       status = phLibNfc_Mgt_DeInitialize(gHWRef, nfc_jni_deinit_callback, (void *)&cb_data);
   1720       REENTRANCE_UNLOCK();
   1721       if (status == NFCSTATUS_PENDING)
   1722       {
   1723          TRACE("phLibNfc_Mgt_DeInitialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
   1724 
   1725          clock_gettime(CLOCK_REALTIME, &ts);
   1726          ts.tv_sec += 5;
   1727 
   1728          /* Wait for callback response */
   1729          if(sem_timedwait(&cb_data.sem, &ts) == -1)
   1730          {
   1731             ALOGW("Operation timed out");
   1732             bStackReset = TRUE;
   1733          }
   1734 
   1735          if(cb_data.status != NFCSTATUS_SUCCESS)
   1736          {
   1737             ALOGE("Failed to deinit the stack");
   1738             bStackReset = TRUE;
   1739          }
   1740       }
   1741       else
   1742       {
   1743          TRACE("phLibNfc_Mgt_DeInitialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
   1744          bStackReset = TRUE;
   1745       }
   1746       nfc_cb_data_deinit(&cb_data);
   1747    }
   1748    else
   1749    {
   1750        ALOGE("Failed to create semaphore (errno=0x%08x)", errno);
   1751        bStackReset = TRUE;
   1752    }
   1753 
   1754    kill_client(nat);
   1755 
   1756    if(bStackReset == TRUE)
   1757    {
   1758       /* Complete deinit. failed, try hard restart of NFC */
   1759       ALOGW("Reseting stack...");
   1760       emergency_recovery(nat);
   1761    }
   1762 
   1763    result = nfc_jni_unconfigure_driver(nat);
   1764 
   1765    TRACE("NFC Deinitialized");
   1766 
   1767    CONCURRENCY_UNLOCK();
   1768 
   1769    return TRUE;
   1770 }
   1771 
   1772 /* Llcp methods */
   1773 
   1774 static jboolean com_android_nfc_NfcManager_doCheckLlcp(JNIEnv *e, jobject o)
   1775 {
   1776    NFCSTATUS ret;
   1777    bool freeData = false;
   1778    jboolean result = JNI_FALSE;
   1779    struct nfc_jni_native_data *nat;
   1780    struct nfc_jni_callback_data  *cb_data;
   1781 
   1782 
   1783    CONCURRENCY_LOCK();
   1784 
   1785    /* Memory allocation for cb_data
   1786     * This is on the heap because it is used by libnfc
   1787     * even after this call has succesfully finished. It is only freed
   1788     * upon link closure in nfc_jni_llcp_linkStatus_callback.
   1789     */
   1790    cb_data = (struct nfc_jni_callback_data*) malloc (sizeof(nfc_jni_callback_data));
   1791 
   1792    /* Retrieve native structure address */
   1793    nat = nfc_jni_get_nat(e, o);
   1794 
   1795    /* Create the local semaphore */
   1796    if (!nfc_cb_data_init(cb_data, (void*)nat))
   1797    {
   1798       goto clean_and_return;
   1799    }
   1800 
   1801    /* Check LLCP compliancy */
   1802    TRACE("phLibNfc_Llcp_CheckLlcp(hLlcpHandle=0x%08x)", hLlcpHandle);
   1803    REENTRANCE_LOCK();
   1804    ret = phLibNfc_Llcp_CheckLlcp(hLlcpHandle,
   1805                                  nfc_jni_checkLlcp_callback,
   1806                                  nfc_jni_llcp_linkStatus_callback,
   1807                                  (void*)cb_data);
   1808    REENTRANCE_UNLOCK();
   1809    /* In case of a NFCIP return NFCSTATUS_SUCCESS and in case of an another protocol
   1810     * NFCSTATUS_PENDING. In this case NFCSTATUS_SUCCESS will also cause the callback. */
   1811    if(ret != NFCSTATUS_PENDING && ret != NFCSTATUS_SUCCESS)
   1812    {
   1813       ALOGE("phLibNfc_Llcp_CheckLlcp() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   1814       freeData = true;
   1815       goto clean_and_return;
   1816    }
   1817    TRACE("phLibNfc_Llcp_CheckLlcp() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   1818 
   1819    /* Wait for callback response */
   1820    if(sem_wait(&cb_data->sem))
   1821    {
   1822       ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
   1823       goto clean_and_return;
   1824    }
   1825 
   1826    if(cb_data->status == NFCSTATUS_SUCCESS)
   1827    {
   1828       result = JNI_TRUE;
   1829    }
   1830 
   1831 clean_and_return:
   1832    nfc_cb_data_deinit(cb_data);
   1833    if (freeData) {
   1834        free(cb_data);
   1835    }
   1836    CONCURRENCY_UNLOCK();
   1837    return result;
   1838 }
   1839 
   1840 static jboolean com_android_nfc_NfcManager_doActivateLlcp(JNIEnv*, jobject)
   1841 {
   1842    NFCSTATUS ret;
   1843    TRACE("phLibNfc_Llcp_Activate(hRemoteDevice=0x%08x)", hLlcpHandle);
   1844    REENTRANCE_LOCK();
   1845    ret = phLibNfc_Llcp_Activate(hLlcpHandle);
   1846    REENTRANCE_UNLOCK();
   1847    if(ret == NFCSTATUS_SUCCESS)
   1848    {
   1849       TRACE("phLibNfc_Llcp_Activate() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   1850       return JNI_TRUE;
   1851    }
   1852    else
   1853    {
   1854       ALOGE("phLibNfc_Llcp_Activate() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   1855       return JNI_FALSE;
   1856    }
   1857 }
   1858 
   1859 
   1860 
   1861 static jobject com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket(JNIEnv *e, jobject o,
   1862         jint nSap, jstring sn)
   1863 {
   1864    NFCSTATUS ret;
   1865    jobject connectionlessSocket = NULL;
   1866    phLibNfc_Handle hLlcpSocket;
   1867    struct nfc_jni_native_data *nat;
   1868    phNfc_sData_t sWorkingBuffer = {NULL, 0};
   1869    phNfc_sData_t serviceName = {NULL, 0};
   1870    phLibNfc_Llcp_sLinkParameters_t sParams;
   1871    jclass clsNativeConnectionlessSocket;
   1872    jfieldID f;
   1873 
   1874    /* Retrieve native structure address */
   1875    nat = nfc_jni_get_nat(e, o);
   1876 
   1877    /* Allocate Working buffer length */
   1878    phLibNfc_Llcp_GetLocalInfo(hLlcpHandle, &sParams);
   1879    sWorkingBuffer.length = sParams.miu + 1; // extra byte for SAP
   1880    sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length);
   1881 
   1882    /* Create socket */
   1883    TRACE("phLibNfc_Llcp_Socket(eType=phFriNfc_LlcpTransport_eConnectionLess, ...)");
   1884    REENTRANCE_LOCK();
   1885    ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionLess,
   1886                               NULL,
   1887                               &sWorkingBuffer,
   1888                               &hLlcpSocket,
   1889                               nfc_jni_llcp_transport_socket_err_callback,
   1890                               (void*)nat);
   1891    REENTRANCE_UNLOCK();
   1892 
   1893    if(ret != NFCSTATUS_SUCCESS)
   1894    {
   1895       lastErrorStatus = ret;
   1896       ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   1897       goto error;
   1898    }
   1899    TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   1900 
   1901    /* Service socket */
   1902    if (sn == NULL) {
   1903        serviceName.buffer = NULL;
   1904        serviceName.length = 0;
   1905    } else {
   1906        serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL);
   1907        serviceName.length = (uint32_t)e->GetStringUTFLength(sn);
   1908    }
   1909 
   1910    /* Bind socket */
   1911    TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap);
   1912    REENTRANCE_LOCK();
   1913    ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, &serviceName);
   1914    REENTRANCE_UNLOCK();
   1915    if(ret != NFCSTATUS_SUCCESS)
   1916    {
   1917       lastErrorStatus = ret;
   1918       ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   1919       /* Close socket created */
   1920       REENTRANCE_LOCK();
   1921       ret = phLibNfc_Llcp_Close(hLlcpSocket);
   1922       REENTRANCE_UNLOCK();
   1923       goto error;
   1924    }
   1925    TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   1926 
   1927 
   1928    /* Create new NativeLlcpConnectionlessSocket object */
   1929    if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpConnectionlessSocket",&(connectionlessSocket)) == -1)
   1930    {
   1931       goto error;
   1932    }
   1933 
   1934    /* Get NativeConnectionless class object */
   1935    clsNativeConnectionlessSocket = e->GetObjectClass(connectionlessSocket);
   1936    if(e->ExceptionCheck())
   1937    {
   1938       goto error;
   1939    }
   1940 
   1941    /* Set socket handle */
   1942    f = e->GetFieldID(clsNativeConnectionlessSocket, "mHandle", "I");
   1943    e->SetIntField(connectionlessSocket, f,(jint)hLlcpSocket);
   1944    TRACE("Connectionless socket Handle = %02x\n",hLlcpSocket);
   1945 
   1946    /* Set the miu link of the connectionless socket */
   1947    f = e->GetFieldID(clsNativeConnectionlessSocket, "mLinkMiu", "I");
   1948    e->SetIntField(connectionlessSocket, f,(jint)PHFRINFC_LLCP_MIU_DEFAULT);
   1949    TRACE("Connectionless socket Link MIU = %d\n",PHFRINFC_LLCP_MIU_DEFAULT);
   1950 
   1951    /* Set socket SAP */
   1952    f = e->GetFieldID(clsNativeConnectionlessSocket, "mSap", "I");
   1953    e->SetIntField(connectionlessSocket, f,(jint)nSap);
   1954    TRACE("Connectionless socket SAP = %d\n",nSap);
   1955 
   1956    return connectionlessSocket;
   1957 error:
   1958    if (serviceName.buffer != NULL) {
   1959       e->ReleaseStringUTFChars(sn, (const char *)serviceName.buffer);
   1960    }
   1961 
   1962    if (sWorkingBuffer.buffer != NULL) {
   1963        free(sWorkingBuffer.buffer);
   1964    }
   1965 
   1966    return NULL;
   1967 }
   1968 
   1969 static jobject com_android_nfc_NfcManager_doCreateLlcpServiceSocket(JNIEnv *e, jobject o, jint nSap, jstring sn, jint miu, jint rw, jint linearBufferLength)
   1970 {
   1971    NFCSTATUS ret;
   1972    phLibNfc_Handle hLlcpSocket;
   1973    phLibNfc_Llcp_sSocketOptions_t sOptions;
   1974    phNfc_sData_t sWorkingBuffer;
   1975    phNfc_sData_t serviceName;
   1976    struct nfc_jni_native_data *nat;
   1977    jobject serviceSocket = NULL;
   1978    jclass clsNativeLlcpServiceSocket;
   1979    jfieldID f;
   1980 
   1981    /* Retrieve native structure address */
   1982    nat = nfc_jni_get_nat(e, o);
   1983 
   1984    /* Set Connection Oriented socket options */
   1985    sOptions.miu = miu;
   1986    sOptions.rw  = rw;
   1987 
   1988    /* Allocate Working buffer length */
   1989    sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength;
   1990    sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length);
   1991 
   1992 
   1993    /* Create socket */
   1994    TRACE("phLibNfc_Llcp_Socket(hRemoteDevice=0x%08x, eType=phFriNfc_LlcpTransport_eConnectionOriented, ...)", hLlcpHandle);
   1995    REENTRANCE_LOCK();
   1996    ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionOriented,
   1997                               &sOptions,
   1998                               &sWorkingBuffer,
   1999                               &hLlcpSocket,
   2000                               nfc_jni_llcp_transport_socket_err_callback,
   2001                               (void*)nat);
   2002    REENTRANCE_UNLOCK();
   2003 
   2004    if(ret != NFCSTATUS_SUCCESS)
   2005    {
   2006       ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   2007       lastErrorStatus = ret;
   2008       goto error;
   2009    }
   2010    TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   2011 
   2012    /* Service socket */
   2013    if (sn == NULL) {
   2014        serviceName.buffer = NULL;
   2015        serviceName.length = 0;
   2016    } else {
   2017        serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL);
   2018        serviceName.length = (uint32_t)e->GetStringUTFLength(sn);
   2019    }
   2020 
   2021    /* Bind socket */
   2022    TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap);
   2023    REENTRANCE_LOCK();
   2024    ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, &serviceName);
   2025    REENTRANCE_UNLOCK();
   2026    if(ret != NFCSTATUS_SUCCESS)
   2027    {
   2028       lastErrorStatus = ret;
   2029       ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   2030       /* Close socket created */
   2031       ret = phLibNfc_Llcp_Close(hLlcpSocket);
   2032       goto error;
   2033    }
   2034    TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   2035 
   2036    TRACE("phLibNfc_Llcp_Listen(hSocket=0x%08x, ...)", hLlcpSocket);
   2037    REENTRANCE_LOCK();
   2038    ret = phLibNfc_Llcp_Listen( hLlcpSocket,
   2039                                nfc_jni_llcp_transport_listen_socket_callback,
   2040                                (void*)hLlcpSocket);
   2041    REENTRANCE_UNLOCK();
   2042 
   2043    if(ret != NFCSTATUS_SUCCESS)
   2044    {
   2045       ALOGE("phLibNfc_Llcp_Listen() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   2046       lastErrorStatus = ret;
   2047       /* Close created socket */
   2048       REENTRANCE_LOCK();
   2049       ret = phLibNfc_Llcp_Close(hLlcpSocket);
   2050       REENTRANCE_UNLOCK();
   2051       goto error;
   2052    }
   2053    TRACE("phLibNfc_Llcp_Listen() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   2054 
   2055    /* Create new NativeLlcpServiceSocket object */
   2056    if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpServiceSocket",&(serviceSocket)) == -1)
   2057    {
   2058       ALOGE("Llcp Socket object creation error");
   2059       goto error;
   2060    }
   2061 
   2062    /* Get NativeLlcpServiceSocket class object */
   2063    clsNativeLlcpServiceSocket = e->GetObjectClass(serviceSocket);
   2064    if(e->ExceptionCheck())
   2065    {
   2066       ALOGE("Llcp Socket get object class error");
   2067       goto error;
   2068    }
   2069 
   2070    /* Set socket handle */
   2071    f = e->GetFieldID(clsNativeLlcpServiceSocket, "mHandle", "I");
   2072    e->SetIntField(serviceSocket, f,(jint)hLlcpSocket);
   2073    TRACE("Service socket Handle = %02x\n",hLlcpSocket);
   2074 
   2075    /* Set socket linear buffer length */
   2076    f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalLinearBufferLength", "I");
   2077    e->SetIntField(serviceSocket, f,(jint)linearBufferLength);
   2078    TRACE("Service socket Linear buffer length = %02x\n",linearBufferLength);
   2079 
   2080    /* Set socket MIU */
   2081    f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalMiu", "I");
   2082    e->SetIntField(serviceSocket, f,(jint)miu);
   2083    TRACE("Service socket MIU = %d\n",miu);
   2084 
   2085    /* Set socket RW */
   2086    f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalRw", "I");
   2087    e->SetIntField(serviceSocket, f,(jint)rw);
   2088    TRACE("Service socket RW = %d\n",rw);
   2089 
   2090    return serviceSocket;
   2091 error:
   2092    if (serviceName.buffer != NULL) {
   2093       e->ReleaseStringUTFChars(sn, (const char *)serviceName.buffer);
   2094    }
   2095    return NULL;
   2096 }
   2097 
   2098 static jobject com_android_nfc_NfcManager_doCreateLlcpSocket(JNIEnv *e, jobject o, jint nSap, jint miu, jint rw, jint linearBufferLength)
   2099 {
   2100    jobject clientSocket = NULL;
   2101    NFCSTATUS ret;
   2102    phLibNfc_Handle hLlcpSocket;
   2103    phLibNfc_Llcp_sSocketOptions_t sOptions;
   2104    phNfc_sData_t sWorkingBuffer;
   2105    struct nfc_jni_native_data *nat;
   2106    jclass clsNativeLlcpSocket;
   2107    jfieldID f;
   2108 
   2109    /* Retrieve native structure address */
   2110    nat = nfc_jni_get_nat(e, o);
   2111 
   2112    /* Set Connection Oriented socket options */
   2113    sOptions.miu = miu;
   2114    sOptions.rw  = rw;
   2115 
   2116    /* Allocate Working buffer length */
   2117    sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength;
   2118    sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length);
   2119 
   2120    /* Create socket */
   2121    TRACE("phLibNfc_Llcp_Socket(eType=phFriNfc_LlcpTransport_eConnectionOriented, ...)");
   2122    REENTRANCE_LOCK();
   2123    ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionOriented,
   2124                               &sOptions,
   2125                               &sWorkingBuffer,
   2126                               &hLlcpSocket,
   2127                               nfc_jni_llcp_transport_socket_err_callback,
   2128                               (void*)nat);
   2129    REENTRANCE_UNLOCK();
   2130 
   2131    if(ret != NFCSTATUS_SUCCESS)
   2132    {
   2133       ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   2134       lastErrorStatus = ret;
   2135       return NULL;
   2136    }
   2137    TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   2138 
   2139    /* Create new NativeLlcpSocket object */
   2140    if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpSocket",&(clientSocket)) == -1)
   2141    {
   2142       ALOGE("Llcp socket object creation error");
   2143       return NULL;
   2144    }
   2145 
   2146    /* Get NativeConnectionless class object */
   2147    clsNativeLlcpSocket = e->GetObjectClass(clientSocket);
   2148    if(e->ExceptionCheck())
   2149    {
   2150       ALOGE("Get class object error");
   2151       return NULL;
   2152    }
   2153 
   2154    /* Test if an SAP number is present */
   2155    if(nSap != 0)
   2156    {
   2157       /* Bind socket */
   2158       TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap);
   2159       REENTRANCE_LOCK();
   2160       ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, NULL);
   2161       REENTRANCE_UNLOCK();
   2162       if(ret != NFCSTATUS_SUCCESS)
   2163       {
   2164          lastErrorStatus = ret;
   2165          ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   2166          /* Close socket created */
   2167          REENTRANCE_LOCK();
   2168          ret = phLibNfc_Llcp_Close(hLlcpSocket);
   2169          REENTRANCE_UNLOCK();
   2170          return NULL;
   2171       }
   2172       TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
   2173 
   2174       /* Set socket SAP */
   2175       f = e->GetFieldID(clsNativeLlcpSocket, "mSap", "I");
   2176       e->SetIntField(clientSocket, f,(jint)nSap);
   2177       TRACE("socket SAP = %d\n",nSap);
   2178    }
   2179 
   2180    /* Set socket handle */
   2181    f = e->GetFieldID(clsNativeLlcpSocket, "mHandle", "I");
   2182    e->SetIntField(clientSocket, f,(jint)hLlcpSocket);
   2183    TRACE("socket Handle = %02x\n",hLlcpSocket);
   2184 
   2185    /* Set socket MIU */
   2186    f = e->GetFieldID(clsNativeLlcpSocket, "mLocalMiu", "I");
   2187    e->SetIntField(clientSocket, f,(jint)miu);
   2188    TRACE("socket MIU = %d\n",miu);
   2189 
   2190    /* Set socket RW */
   2191    f = e->GetFieldID(clsNativeLlcpSocket, "mLocalRw", "I");
   2192    e->SetIntField(clientSocket, f,(jint)rw);
   2193    TRACE("socket RW = %d\n",rw);
   2194 
   2195 
   2196    return clientSocket;
   2197 }
   2198 
   2199 static jint com_android_nfc_NfcManager_doGetLastError(JNIEnv*, jobject)
   2200 {
   2201    TRACE("Last Error Status = 0x%02x",lastErrorStatus);
   2202 
   2203    if(lastErrorStatus == NFCSTATUS_BUFFER_TOO_SMALL)
   2204    {
   2205       return ERROR_BUFFER_TOO_SMALL;
   2206    }
   2207    else if(lastErrorStatus == NFCSTATUS_INSUFFICIENT_RESOURCES)
   2208    {
   2209       return  ERROR_INSUFFICIENT_RESOURCES;
   2210    }
   2211    else
   2212    {
   2213       return lastErrorStatus;
   2214    }
   2215 }
   2216 
   2217 static void com_android_nfc_NfcManager_doAbort(JNIEnv*, jobject)
   2218 {
   2219     emergency_recovery(NULL);
   2220 }
   2221 
   2222 static void com_android_nfc_NfcManager_doSetP2pInitiatorModes(JNIEnv *e, jobject o,
   2223         jint modes)
   2224 {
   2225     ALOGE("Setting init modes to %x", modes);
   2226     struct nfc_jni_native_data *nat = NULL;
   2227     nat = nfc_jni_get_nat(e, o);
   2228     nat->p2p_initiator_modes = modes;
   2229 }
   2230 
   2231 static void com_android_nfc_NfcManager_doSetP2pTargetModes(JNIEnv *e, jobject o,
   2232         jint modes)
   2233 {
   2234     ALOGE("Setting target modes to %x", modes);
   2235     struct nfc_jni_native_data *nat = NULL;
   2236     nat = nfc_jni_get_nat(e, o);
   2237     nat->p2p_target_modes = modes;
   2238 }
   2239 
   2240 static bool performDownload(struct nfc_jni_native_data* nat, bool takeLock) {
   2241     bool result = FALSE;
   2242     int load_result;
   2243     bool wasDisabled = FALSE;
   2244     uint8_t OutputBuffer[1];
   2245     uint8_t InputBuffer[1];
   2246     NFCSTATUS status = NFCSTATUS_FAILED;
   2247     struct nfc_jni_callback_data cb_data;
   2248 
   2249     /* Create the local semaphore */
   2250     if (!nfc_cb_data_init(&cb_data, NULL))
   2251     {
   2252        result = FALSE;
   2253        goto clean_and_return;
   2254     }
   2255 
   2256     if (takeLock)
   2257     {
   2258         CONCURRENCY_LOCK();
   2259     }
   2260 
   2261     /* Initialize Driver */
   2262     if(!driverConfigured)
   2263     {
   2264         result = nfc_jni_configure_driver(nat);
   2265         wasDisabled = TRUE;
   2266     }
   2267     TRACE("com_android_nfc_NfcManager_doDownload()");
   2268 
   2269     TRACE("Go in Download Mode");
   2270     phLibNfc_Download_Mode();
   2271 
   2272     TRACE("Load new Firmware Image");
   2273     load_result = phLibNfc_Load_Firmware_Image();
   2274     if(load_result != 0)
   2275     {
   2276         TRACE("Load new Firmware Image - status = %d",load_result);
   2277         result = FALSE;
   2278         goto clean_and_return;
   2279     }
   2280 
   2281     // Download
   2282     gInputParam.buffer  = InputBuffer;
   2283     gInputParam.length  = 0x01;
   2284     gOutputParam.buffer = OutputBuffer;
   2285     gOutputParam.length = 0x01;
   2286 
   2287     ALOGD("Download new Firmware");
   2288     REENTRANCE_LOCK();
   2289     status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_FW_DOWNLOAD, &gInputParam, &gOutputParam, nfc_jni_ioctl_callback, (void *)&cb_data);
   2290     REENTRANCE_UNLOCK();
   2291     if(status != NFCSTATUS_PENDING)
   2292     {
   2293         ALOGE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
   2294         result = FALSE;
   2295         goto clean_and_return;
   2296     }
   2297     TRACE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
   2298 
   2299     /* Wait for callback response */
   2300     if(sem_wait(&cb_data.sem))
   2301     {
   2302        ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
   2303        result = FALSE;
   2304        goto clean_and_return;
   2305     }
   2306 
   2307     /* NOTE: we will get NFCSTATUS_FEATURE_NOT_SUPPORTED when we
   2308        try to download an old-style firmware on top of a new-style
   2309        firmware.  Hence, this is expected behavior, and not an
   2310        error condition. */
   2311     if(cb_data.status != NFCSTATUS_SUCCESS && cb_data.status != NFCSTATUS_FEATURE_NOT_SUPPORTED)
   2312     {
   2313         TRACE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
   2314         result = FALSE;
   2315         goto clean_and_return;
   2316     }
   2317 
   2318     if(cb_data.status == NFCSTATUS_FEATURE_NOT_SUPPORTED)
   2319     {
   2320         ALOGW("Old-style firmware not installed on top of new-style firmware. Using existing firmware in the chip.");
   2321     }
   2322 
   2323     /*Download is successful*/
   2324     result = TRUE;
   2325 clean_and_return:
   2326     TRACE("phLibNfc_HW_Reset()");
   2327     phLibNfc_HW_Reset();
   2328     /* Deinitialize Driver */
   2329     if(wasDisabled)
   2330     {
   2331         result = nfc_jni_unconfigure_driver(nat);
   2332     }
   2333     if (takeLock)
   2334     {
   2335         CONCURRENCY_UNLOCK();
   2336     }
   2337     nfc_cb_data_deinit(&cb_data);
   2338     return result;
   2339 }
   2340 
   2341 static jboolean com_android_nfc_NfcManager_doDownload(JNIEnv *e, jobject o)
   2342 {
   2343     struct nfc_jni_native_data *nat = NULL;
   2344     nat = nfc_jni_get_nat(e, o);
   2345     return performDownload(nat, true);
   2346 }
   2347 
   2348 static jstring com_android_nfc_NfcManager_doDump(JNIEnv *e, jobject)
   2349 {
   2350     char buffer[100];
   2351     snprintf(buffer, sizeof(buffer), "libnfc llc error_count=%u", libnfc_llc_error_count);
   2352     return e->NewStringUTF(buffer);
   2353 }
   2354 
   2355 /*
   2356  * JNI registration.
   2357  */
   2358 static JNINativeMethod gMethods[] =
   2359 {
   2360    {"doDownload", "()Z",
   2361         (void *)com_android_nfc_NfcManager_doDownload},
   2362 
   2363    {"initializeNativeStructure", "()Z",
   2364       (void *)com_android_nfc_NfcManager_init_native_struc},
   2365 
   2366    {"doInitialize", "()Z",
   2367       (void *)com_android_nfc_NfcManager_initialize},
   2368 
   2369    {"doDeinitialize", "()Z",
   2370       (void *)com_android_nfc_NfcManager_deinitialize},
   2371 
   2372    {"doEnableDiscovery", "(IZZZ)V",
   2373       (void *)com_android_nfc_NfcManager_enableDiscovery},
   2374 
   2375    {"doCheckLlcp", "()Z",
   2376       (void *)com_android_nfc_NfcManager_doCheckLlcp},
   2377 
   2378    {"doActivateLlcp", "()Z",
   2379       (void *)com_android_nfc_NfcManager_doActivateLlcp},
   2380 
   2381    {"doCreateLlcpConnectionlessSocket", "(ILjava/lang/String;)Lcom/android/nfc/dhimpl/NativeLlcpConnectionlessSocket;",
   2382       (void *)com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket},
   2383 
   2384    {"doCreateLlcpServiceSocket", "(ILjava/lang/String;III)Lcom/android/nfc/dhimpl/NativeLlcpServiceSocket;",
   2385       (void *)com_android_nfc_NfcManager_doCreateLlcpServiceSocket},
   2386 
   2387    {"doCreateLlcpSocket", "(IIII)Lcom/android/nfc/dhimpl/NativeLlcpSocket;",
   2388       (void *)com_android_nfc_NfcManager_doCreateLlcpSocket},
   2389 
   2390    {"doGetLastError", "()I",
   2391       (void *)com_android_nfc_NfcManager_doGetLastError},
   2392 
   2393    {"disableDiscovery", "()V",
   2394       (void *)com_android_nfc_NfcManager_disableDiscovery},
   2395 
   2396    {"doSetTimeout", "(II)Z",
   2397       (void *)com_android_nfc_NfcManager_doSetTimeout},
   2398 
   2399    {"doGetTimeout", "(I)I",
   2400       (void *)com_android_nfc_NfcManager_doGetTimeout},
   2401 
   2402    {"doResetTimeouts", "()V",
   2403       (void *)com_android_nfc_NfcManager_doResetTimeouts},
   2404 
   2405    {"doAbort", "()V",
   2406       (void *)com_android_nfc_NfcManager_doAbort},
   2407 
   2408    {"doSetP2pInitiatorModes","(I)V",
   2409       (void *)com_android_nfc_NfcManager_doSetP2pInitiatorModes},
   2410 
   2411    {"doSetP2pTargetModes","(I)V",
   2412       (void *)com_android_nfc_NfcManager_doSetP2pTargetModes},
   2413 
   2414    {"doDump", "()Ljava/lang/String;",
   2415       (void *)com_android_nfc_NfcManager_doDump},
   2416 };
   2417 
   2418 
   2419 int register_com_android_nfc_NativeNfcManager(JNIEnv *e)
   2420 {
   2421     nfc_jni_native_monitor_t *nfc_jni_native_monitor;
   2422 
   2423    nfc_jni_native_monitor = nfc_jni_init_monitor();
   2424    if(nfc_jni_native_monitor == NULL)
   2425    {
   2426       ALOGE("NFC Manager cannot recover native monitor %x\n", errno);
   2427       return -1;
   2428    }
   2429 
   2430    return jniRegisterNativeMethods(e,
   2431       "com/android/nfc/dhimpl/NativeNfcManager",
   2432       gMethods, NELEM(gMethods));
   2433 }
   2434 
   2435 } /* namespace android */
   2436