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