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