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