1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <errno.h>
18 #include <pthread.h>
19 #include <semaphore.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <math.h>
23 #include <sys/queue.h>
24 #include <hardware/hardware.h>
25 #include <hardware/nfc.h>
26 #include <cutils/properties.h>
27 #include <ScopedLocalRef.h>
28 
29 #include "com_android_nfc.h"
30 
31 #define ERROR_BUFFER_TOO_SMALL       -12
32 #define ERROR_INSUFFICIENT_RESOURCES -9
33 
34 extern uint32_t libnfc_llc_error_count;
35 
36 static phLibNfc_sConfig_t   gDrvCfg;
37 void   *gHWRef;
38 static phNfc_sData_t gInputParam;
39 static phNfc_sData_t gOutputParam;
40 
41 uint8_t device_connected_flag;
42 static bool driverConfigured = FALSE;
43 
44 static phLibNfc_Handle              hLlcpHandle;
45 static NFCSTATUS                    lastErrorStatus = NFCSTATUS_FAILED;
46 static phLibNfc_Llcp_eLinkStatus_t  g_eLinkStatus = phFriNfc_LlcpMac_eLinkDefault;
47 
48 static jmethodID cached_NfcManager_notifyNdefMessageListeners;
49 static jmethodID cached_NfcManager_notifyLlcpLinkActivation;
50 static jmethodID cached_NfcManager_notifyLlcpLinkDeactivated;
51 static jmethodID cached_NfcManager_notifyTargetDeselected;
52 
53 static jmethodID cached_NfcManager_notifyRfFieldActivated;
54 static jmethodID cached_NfcManager_notifyRfFieldDeactivated;
55 namespace android {
56 
57 phLibNfc_Handle     storedHandle = 0;
58 
59 struct nfc_jni_native_data *exported_nat = NULL;
60 
61 /* Internal functions declaration */
62 static void *nfc_jni_client_thread(void *arg);
63 static void nfc_jni_init_callback(void *pContext, NFCSTATUS status);
64 static void nfc_jni_deinit_callback(void *pContext, NFCSTATUS status);
65 static void nfc_jni_discover_callback(void *pContext, NFCSTATUS status);
66 static void nfc_jni_se_set_mode_callback(void *context,
67         phLibNfc_Handle handle, NFCSTATUS status);
68 static void nfc_jni_llcpcfg_callback(void *pContext, NFCSTATUS status);
69 static void nfc_jni_start_discovery_locked(struct nfc_jni_native_data *nat, bool resume);
70 static void nfc_jni_Discovery_notification_callback(void *pContext,
71         phLibNfc_RemoteDevList_t *psRemoteDevList,
72         uint8_t uNofRemoteDev, NFCSTATUS status);
73 static void nfc_jni_transaction_callback(void *context,
74         phLibNfc_eSE_EvtType_t evt_type, phLibNfc_Handle handle,
75         phLibNfc_uSeEvtInfo_t *evt_info, NFCSTATUS status);
76 static bool performDownload(struct nfc_jni_native_data *nat, bool takeLock);
77 
78 extern void set_target_activationBytes(JNIEnv *e, jobject tag,
79         phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo);
80 extern void set_target_pollBytes(JNIEnv *e, jobject tag,
81         phLibNfc_sRemoteDevInformation_t *psRemoteDevInfo);
82 
83 /*
84  * Deferred callback called when client thread must be exited
85  */
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 *,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 *)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 *)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    NFCSTATUS ret;
910    const char * typeName;
911    struct timespec ts;
912    phNfc_sData_t data;
913    int i;
914    int target_index = 0; // Target that will be reported (if multiple can be >0)
915 
916    struct nfc_jni_native_data* nat = (struct nfc_jni_native_data *)pContext;
917 
918    JNIEnv *e;
919    nat->vm->GetEnv( (void **)&e, nat->env_version);
920 
921    if(status == NFCSTATUS_DESELECTED)
922    {
923       LOG_CALLBACK("nfc_jni_Discovery_notification_callback: Target deselected", status);
924 
925       /* Notify manager that a target was deselected */
926       e->CallVoidMethod(nat->manager, cached_NfcManager_notifyTargetDeselected);
927       if(e->ExceptionCheck())
928       {
929          ALOGE("Exception occurred");
930          kill_client(nat);
931       }
932    }
933    else
934    {
935       LOG_CALLBACK("nfc_jni_Discovery_notification_callback", status);
936       TRACE("Discovered %d tags", uNofRemoteDev);
937 
938       target_index = find_preferred_target(psRemoteDevList, uNofRemoteDev);
939 
940       ScopedLocalRef<jobject> tag(e, NULL);
941 
942       /* Reset device connected flag */
943       device_connected_flag = 1;
944       phLibNfc_sRemoteDevInformation_t *remDevInfo = psRemoteDevList[target_index].psRemoteDevInfo;
945       phLibNfc_Handle remDevHandle = psRemoteDevList[target_index].hTargetDev;
946       if((remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator)
947           || (remDevInfo->RemDevType == phNfc_eNfcIP1_Target))
948       {
949          ScopedLocalRef<jclass> tag_cls(e, e->GetObjectClass(nat->cached_P2pDevice));
950          if(e->ExceptionCheck())
951          {
952             ALOGE("Get Object Class Error");
953             kill_client(nat);
954             return;
955          }
956 
957          /* New target instance */
958          jmethodID ctor = e->GetMethodID(tag_cls.get(), "<init>", "()V");
959          tag.reset(e->NewObject(tag_cls.get(), ctor));
960 
961          /* Set P2P Target mode */
962          jfieldID f = e->GetFieldID(tag_cls.get(), "mMode", "I");
963 
964          if(remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator)
965          {
966             ALOGD("Discovered P2P Initiator");
967             e->SetIntField(tag.get(), f, (jint)MODE_P2P_INITIATOR);
968          }
969          else
970          {
971             ALOGD("Discovered P2P Target");
972             e->SetIntField(tag.get(), f, (jint)MODE_P2P_TARGET);
973          }
974 
975          if(remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator)
976          {
977             /* Set General Bytes */
978             f = e->GetFieldID(tag_cls.get(), "mGeneralBytes", "[B");
979 
980            TRACE("General Bytes length =");
981            for(i=0;i<remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length;i++)
982            {
983                ALOGD("%02x ", remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo[i]);
984            }
985 
986             ScopedLocalRef<jbyteArray> generalBytes(e, e->NewByteArray(remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length));
987 
988             e->SetByteArrayRegion(generalBytes.get(), 0,
989                                   remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo_Length,
990                                   (jbyte *)remDevInfo->RemoteDevInfo.NfcIP_Info.ATRInfo);
991             e->SetObjectField(tag.get(), f, generalBytes.get());
992          }
993 
994          /* Set tag handle */
995          f = e->GetFieldID(tag_cls.get(), "mHandle", "I");
996          e->SetIntField(tag.get(), f,(jint)remDevHandle);
997          TRACE("Target handle = 0x%08x",remDevHandle);
998       }
999       else
1000       {
1001         ScopedLocalRef<jclass> tag_cls(e, e->GetObjectClass(nat->cached_NfcTag));
1002         if(e->ExceptionCheck())
1003         {
1004             kill_client(nat);
1005             return;
1006         }
1007 
1008         /* New tag instance */
1009         jmethodID ctor = e->GetMethodID(tag_cls.get(), "<init>", "()V");
1010         tag.reset(e->NewObject(tag_cls.get(), ctor));
1011 
1012         bool multi_protocol = false;
1013 
1014         if(status == NFCSTATUS_MULTIPLE_PROTOCOLS)
1015         {
1016             TRACE("Multiple Protocol TAG detected\n");
1017             multi_protocol = true;
1018         }
1019 
1020         /* Set tag UID */
1021         jfieldID f = e->GetFieldID(tag_cls.get(), "mUid", "[B");
1022         data = get_target_uid(remDevInfo);
1023         ScopedLocalRef<jbyteArray> tagUid(e, e->NewByteArray(data.length));
1024         if(data.length > 0)
1025         {
1026            e->SetByteArrayRegion(tagUid.get(), 0, data.length, (jbyte *)data.buffer);
1027         }
1028         e->SetObjectField(tag.get(), f, tagUid.get());
1029 
1030         /* Generate technology list */
1031         ScopedLocalRef<jintArray> techList(e, NULL);
1032         ScopedLocalRef<jintArray> handleList(e, NULL);
1033         ScopedLocalRef<jintArray> typeList(e, NULL);
1034         nfc_jni_get_technology_tree(e, psRemoteDevList,
1035                 multi_protocol ? uNofRemoteDev : 1,
1036                 &techList, &handleList, &typeList);
1037 
1038         /* Push the technology list into the java object */
1039         f = e->GetFieldID(tag_cls.get(), "mTechList", "[I");
1040         e->SetObjectField(tag.get(), f, techList.get());
1041 
1042         f = e->GetFieldID(tag_cls.get(), "mTechHandles", "[I");
1043         e->SetObjectField(tag.get(), f, handleList.get());
1044 
1045         f = e->GetFieldID(tag_cls.get(), "mTechLibNfcTypes", "[I");
1046         e->SetObjectField(tag.get(), f, typeList.get());
1047 
1048         f = e->GetFieldID(tag_cls.get(), "mConnectedTechIndex", "I");
1049         e->SetIntField(tag.get(), f,(jint)-1);
1050 
1051         f = e->GetFieldID(tag_cls.get(), "mConnectedHandle", "I");
1052         e->SetIntField(tag.get(), f,(jint)-1);
1053 
1054         set_target_pollBytes(e, tag.get(), psRemoteDevList->psRemoteDevInfo);
1055 
1056         set_target_activationBytes(e, tag.get(), psRemoteDevList->psRemoteDevInfo);
1057       }
1058 
1059       storedHandle = remDevHandle;
1060       if (nat->tag != NULL) {
1061           e->DeleteGlobalRef(nat->tag);
1062       }
1063       nat->tag = e->NewGlobalRef(tag.get());
1064 
1065       /* Notify the service */
1066       TRACE("Notify Nfc Service");
1067       if((remDevInfo->RemDevType == phNfc_eNfcIP1_Initiator)
1068           || (remDevInfo->RemDevType == phNfc_eNfcIP1_Target))
1069       {
1070          /* Store the handle of the P2P device */
1071          hLlcpHandle = remDevHandle;
1072 
1073          /* Notify manager that new a P2P device was found */
1074          e->CallVoidMethod(nat->manager, cached_NfcManager_notifyLlcpLinkActivation, tag.get());
1075          if(e->ExceptionCheck())
1076          {
1077             ALOGE("Exception occurred");
1078             kill_client(nat);
1079          }
1080       }
1081       else
1082       {
1083          /* Notify manager that new a tag was found */
1084          e->CallVoidMethod(nat->manager, cached_NfcManager_notifyNdefMessageListeners, tag.get());
1085          if(e->ExceptionCheck())
1086          {
1087             ALOGE("Exception occurred");
1088             kill_client(nat);
1089          }
1090       }
1091    }
1092 }
1093 
nfc_jni_init_callback(void * pContext,NFCSTATUS status)1094 static void nfc_jni_init_callback(void *pContext, NFCSTATUS status)
1095 {
1096    struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
1097 
1098    LOG_CALLBACK("nfc_jni_init_callback", status);
1099 
1100    pContextData->status = status;
1101    sem_post(&pContextData->sem);
1102 }
1103 
nfc_jni_deinit_callback(void * pContext,NFCSTATUS status)1104 static void nfc_jni_deinit_callback(void *pContext, NFCSTATUS status)
1105 {
1106    struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
1107 
1108    LOG_CALLBACK("nfc_jni_deinit_callback", status);
1109 
1110    pContextData->status = status;
1111    sem_post(&pContextData->sem);
1112 }
1113 
1114 /* Set Secure Element mode callback*/
nfc_jni_smartMX_setModeCb(void * pContext,phLibNfc_Handle,NFCSTATUS status)1115 static void nfc_jni_smartMX_setModeCb (void*            pContext,
1116                                        phLibNfc_Handle  /*hSecureElement*/,
1117                                        NFCSTATUS        status)
1118 {
1119    struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
1120 
1121    LOG_CALLBACK("nfc_jni_smartMX_setModeCb", status);
1122 
1123    pContextData->status = status;
1124    sem_post(&pContextData->sem);
1125 }
1126 
1127 /* Card Emulation callback */
nfc_jni_transaction_callback(void * context,phLibNfc_eSE_EvtType_t evt_type,phLibNfc_Handle,phLibNfc_uSeEvtInfo_t * evt_info,NFCSTATUS status)1128 static void nfc_jni_transaction_callback(void *context,
1129    phLibNfc_eSE_EvtType_t evt_type, phLibNfc_Handle /*handle*/,
1130    phLibNfc_uSeEvtInfo_t *evt_info, NFCSTATUS status)
1131 {
1132     JNIEnv *e;
1133     jobject tmp_array = NULL;
1134     jobject mifare_block = NULL;
1135     struct nfc_jni_native_data *nat;
1136     phNfc_sData_t *aid;
1137     phNfc_sData_t *mifare_command;
1138     struct nfc_jni_callback_data *pCallbackData;
1139     int i=0;
1140 
1141     LOG_CALLBACK("nfc_jni_transaction_callback", status);
1142 
1143     nat = (struct nfc_jni_native_data *)context;
1144 
1145     nat->vm->GetEnv( (void **)&e, nat->env_version);
1146 
1147     if(status == NFCSTATUS_SUCCESS)
1148     {
1149         switch(evt_type)
1150         {
1151             case phLibNfc_eSE_EvtStartTransaction:
1152             {
1153                 TRACE("> SE EVT_START_TRANSACTION");
1154             }break;
1155 
1156             case phLibNfc_eSE_EvtApduReceived:
1157             {
1158                 TRACE("> SE EVT_APDU_RECEIVED");
1159             }break;
1160 
1161             case phLibNfc_eSE_EvtCardRemoval:
1162             {
1163                 TRACE("> SE EVT_EMV_CARD_REMOVAL");
1164             }break;
1165 
1166             case phLibNfc_eSE_EvtMifareAccess:
1167             {
1168                 TRACE("> SE EVT_MIFARE_ACCESS");
1169             }break;
1170 
1171             case phLibNfc_eSE_EvtFieldOn:
1172             {
1173                 TRACE("> SE EVT_FIELD_ON");
1174                 e->CallVoidMethod(nat->manager, cached_NfcManager_notifyRfFieldActivated);
1175             }break;
1176 
1177             case phLibNfc_eSE_EvtFieldOff:
1178             {
1179                 TRACE("> SE EVT_FIELD_OFF");
1180                 e->CallVoidMethod(nat->manager, cached_NfcManager_notifyRfFieldDeactivated);
1181             }break;
1182 
1183             default:
1184             {
1185                 TRACE("Unknown SE event");
1186             }break;
1187         }
1188     }
1189     else
1190     {
1191         ALOGE("SE transaction notification error");
1192         goto error;
1193     }
1194 
1195     /* Function finished, now clean and return */
1196     goto clean_and_return;
1197 
1198  error:
1199     /* In case of error, just discard the notification */
1200     ALOGE("Failed to send SE transaction notification");
1201     e->ExceptionClear();
1202 
1203  clean_and_return:
1204     if(tmp_array != NULL)
1205     {
1206        e->DeleteLocalRef(tmp_array);
1207     }
1208 }
1209 
nfc_jni_se_set_mode_callback(void * pContext,phLibNfc_Handle,NFCSTATUS status)1210 static void nfc_jni_se_set_mode_callback(void *pContext,
1211    phLibNfc_Handle /*handle*/, NFCSTATUS status)
1212 {
1213    struct nfc_jni_callback_data * pContextData =  (struct nfc_jni_callback_data*)pContext;
1214 
1215    LOG_CALLBACK("nfc_jni_se_set_mode_callback", status);
1216 
1217    pContextData->status = status;
1218    sem_post(&pContextData->sem);
1219 }
1220 
1221 /*
1222  * NFCManager methods
1223  */
1224 
nfc_jni_start_discovery_locked(struct nfc_jni_native_data * nat,bool resume)1225 static void nfc_jni_start_discovery_locked(struct nfc_jni_native_data *nat, bool resume)
1226 {
1227    NFCSTATUS ret;
1228    struct nfc_jni_callback_data cb_data;
1229    int numRetries = 3;
1230 
1231    /* Create the local semaphore */
1232    if (!nfc_cb_data_init(&cb_data, NULL))
1233    {
1234       goto clean_and_return;
1235    }
1236    /* Reset the PN544 ISO XCHG / sw watchdog timeouts */
1237    nfc_jni_reset_timeout_values();
1238 
1239    /* Reload the p2p modes */
1240    nat->discovery_cfg.NfcIP_Mode = nat->p2p_initiator_modes;  //initiator
1241    nat->discovery_cfg.NfcIP_Target_Mode = nat->p2p_target_modes;  //target
1242    nat->discovery_cfg.NfcIP_Tgt_Disable = FALSE;
1243 
1244    /* Reset device connected flag */
1245    device_connected_flag = 0;
1246 configure:
1247    /* Start Polling loop */
1248    TRACE("******  Start NFC Discovery ******");
1249    REENTRANCE_LOCK();
1250    ret = phLibNfc_Mgt_ConfigureDiscovery(resume ? NFC_DISCOVERY_RESUME : NFC_DISCOVERY_CONFIG,
1251       nat->discovery_cfg, nfc_jni_discover_callback, (void *)&cb_data);
1252    REENTRANCE_UNLOCK();
1253    TRACE("phLibNfc_Mgt_ConfigureDiscovery(%s-%s-%s-%s-%s-%s, %s-%x-%x) returned 0x%08x\n",
1254       nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A==TRUE?"3A":"",
1255       nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B==TRUE?"3B":"",
1256       nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212==TRUE?"F2":"",
1257       nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424==TRUE?"F4":"",
1258       nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive==TRUE?"NFC":"",
1259       nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693==TRUE?"RFID":"",
1260       nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation==FALSE?"CE":"",
1261       nat->discovery_cfg.NfcIP_Mode, nat->discovery_cfg.Duration, ret);
1262 
1263    if (ret == NFCSTATUS_BUSY && numRetries-- > 0)
1264    {
1265       TRACE("ConfigDiscovery BUSY, retrying");
1266       usleep(1000000);
1267       goto configure;
1268    }
1269 
1270    if(ret != NFCSTATUS_PENDING)
1271    {
1272       emergency_recovery(nat);
1273       goto clean_and_return;
1274    }
1275 
1276    /* Wait for callback response */
1277    if(sem_wait(&cb_data.sem))
1278    {
1279       ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
1280       goto clean_and_return;
1281    }
1282 
1283 clean_and_return:
1284    nfc_cb_data_deinit(&cb_data);
1285 }
1286 
nfc_jni_stop_discovery_locked(struct nfc_jni_native_data * nat)1287 static void nfc_jni_stop_discovery_locked(struct nfc_jni_native_data *nat)
1288 {
1289    phLibNfc_sADD_Cfg_t discovery_cfg;
1290    NFCSTATUS ret;
1291    struct nfc_jni_callback_data cb_data;
1292    int numRetries = 3;
1293 
1294    /* Create the local semaphore */
1295    if (!nfc_cb_data_init(&cb_data, NULL))
1296    {
1297       goto clean_and_return;
1298    }
1299 
1300    discovery_cfg.PollDevInfo.PollEnabled = 0;
1301    discovery_cfg.NfcIP_Mode = phNfc_eDefaultP2PMode;
1302    discovery_cfg.NfcIP_Target_Mode = 0;
1303    discovery_cfg.NfcIP_Tgt_Disable = TRUE;
1304 
1305 configure:
1306    /* Start Polling loop */
1307    TRACE("******  Stop NFC Discovery ******");
1308    REENTRANCE_LOCK();
1309    ret = phLibNfc_Mgt_ConfigureDiscovery(NFC_DISCOVERY_CONFIG,discovery_cfg, nfc_jni_discover_callback, (void *)&cb_data);
1310    REENTRANCE_UNLOCK();
1311    TRACE("phLibNfc_Mgt_ConfigureDiscovery(%s-%s-%s-%s-%s-%s, %s-%x-%x) returned 0x%08x\n",
1312       discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A==TRUE?"3A":"",
1313       discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B==TRUE?"3B":"",
1314       discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212==TRUE?"F2":"",
1315       discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424==TRUE?"F4":"",
1316       discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive==TRUE?"NFC":"",
1317       discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693==TRUE?"RFID":"",
1318       discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation==FALSE?"CE":"",
1319       discovery_cfg.NfcIP_Mode, discovery_cfg.Duration, ret);
1320 
1321    if (ret == NFCSTATUS_BUSY && numRetries-- > 0)
1322    {
1323       TRACE("ConfigDiscovery BUSY, retrying");
1324       usleep(1000000);
1325       goto configure;
1326    }
1327 
1328    if(ret != NFCSTATUS_PENDING)
1329    {
1330       ALOGE("[STOP] ConfigDiscovery returned %x", ret);
1331       emergency_recovery(nat);
1332    }
1333 
1334    /* Wait for callback response */
1335    if(sem_wait(&cb_data.sem))
1336    {
1337       ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
1338       goto clean_and_return;
1339    }
1340 
1341 clean_and_return:
1342    nfc_cb_data_deinit(&cb_data);
1343 }
1344 
1345 
com_android_nfc_NfcManager_disableDiscovery(JNIEnv * e,jobject o)1346 static void com_android_nfc_NfcManager_disableDiscovery(JNIEnv *e, jobject o)
1347 {
1348     struct nfc_jni_native_data *nat;
1349 
1350     CONCURRENCY_LOCK();
1351 
1352     /* Retrieve native structure address */
1353     nat = nfc_jni_get_nat(e, o);
1354 
1355     nfc_jni_stop_discovery_locked(nat);
1356 
1357     CONCURRENCY_UNLOCK();
1358 
1359 }
1360 
1361 // TODO: use enable_lptd
com_android_nfc_NfcManager_enableDiscovery(JNIEnv * e,jobject o,jint modes,jboolean,jboolean reader_mode,jboolean enable_p2p,jboolean restart)1362 static void com_android_nfc_NfcManager_enableDiscovery(JNIEnv *e, jobject o, jint modes,
1363         jboolean, jboolean reader_mode, jboolean enable_p2p, jboolean restart)
1364 {
1365     NFCSTATUS ret;
1366     struct nfc_jni_native_data *nat;
1367 
1368     CONCURRENCY_LOCK();
1369 
1370     nat = nfc_jni_get_nat(e, o);
1371 
1372    /* Register callback for remote device notifications.
1373     * Must re-register every time we turn on discovery, since other operations
1374     * (such as opening the Secure Element) can change the remote device
1375     * notification callback*/
1376    REENTRANCE_LOCK();
1377    ret = phLibNfc_RemoteDev_NtfRegister(&nat->registry_info, nfc_jni_Discovery_notification_callback, (void *)nat);
1378    REENTRANCE_UNLOCK();
1379    if(ret != NFCSTATUS_SUCCESS)
1380    {
1381         ALOGD("pphLibNfc_RemoteDev_NtfRegister returned 0x%02x",ret);
1382         goto clean_and_return;
1383    }
1384    TRACE("phLibNfc_RemoteDev_NtfRegister(%s-%s-%s-%s-%s-%s-%s-%s) returned 0x%x\n",
1385       nat->registry_info.Jewel==TRUE?"J":"",
1386       nat->registry_info.MifareUL==TRUE?"UL":"",
1387       nat->registry_info.MifareStd==TRUE?"Mi":"",
1388       nat->registry_info.Felica==TRUE?"F":"",
1389       nat->registry_info.ISO14443_4A==TRUE?"4A":"",
1390       nat->registry_info.ISO14443_4B==TRUE?"4B":"",
1391       nat->registry_info.NFC==TRUE?"P2P":"",
1392       nat->registry_info.ISO15693==TRUE?"R":"", ret);
1393 
1394     if (modes != 0)
1395     {
1396 
1397         if (enable_p2p)
1398         {
1399             nat->p2p_initiator_modes = phNfc_eP2P_ALL;
1400             nat->p2p_target_modes = 0x0E; // All passive except 106, active
1401             nat->discovery_cfg.Duration = 300000; /* in ms */
1402         }
1403         else
1404         {
1405             nat->p2p_initiator_modes = 0;
1406             nat->p2p_target_modes = 0;
1407             nat->discovery_cfg.Duration = 200000; /* in ms */
1408 
1409         }
1410 
1411         if (reader_mode)
1412         {
1413             nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = TRUE;
1414             nat->discovery_cfg.Duration = 200000; /* in ms */
1415         }
1416         else
1417         {
1418             nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = FALSE;
1419             nat->discovery_cfg.Duration = 300000; /* in ms */
1420         }
1421         nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A = (modes & 0x01) != 0;
1422         nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B = (modes & 0x02) != 0;
1423         nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212 = (modes & 0x04) != 0;
1424         nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424 = (modes & 0x04) != 0;
1425         nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693 = (modes & 0x08) != 0;
1426     }
1427 
1428     nfc_jni_start_discovery_locked(nat, false);
1429 clean_and_return:
1430     CONCURRENCY_UNLOCK();
1431 }
1432 
com_android_nfc_NfcManager_doResetTimeouts(JNIEnv *,jobject)1433 static void com_android_nfc_NfcManager_doResetTimeouts(JNIEnv*, jobject) {
1434     CONCURRENCY_LOCK();
1435     nfc_jni_reset_timeout_values();
1436     CONCURRENCY_UNLOCK();
1437 }
1438 
setFelicaTimeout(jint timeout)1439 static void setFelicaTimeout(jint timeout) {
1440    // The Felica timeout is configurable in the PN544 upto a maximum of 255 ms.
1441    // It can be set to 0 to disable the timeout altogether, in which case we
1442    // use the sw watchdog as a fallback.
1443    if (timeout <= 255) {
1444        phLibNfc_SetFelicaTimeout(timeout);
1445    } else {
1446        // Disable hw timeout, use sw watchdog for timeout
1447        phLibNfc_SetFelicaTimeout(0);
1448        phLibNfc_SetHciTimeout(timeout);
1449    }
1450 
1451 }
1452 // Calculates ceiling log2 of value
log2(int value)1453 static unsigned int log2(int value) {
1454     unsigned int ret = 0;
1455     bool isPowerOf2 = ((value & (value - 1)) == 0);
1456     while ( (value >> ret) > 1 ) ret++;
1457     if (!isPowerOf2) ret++;
1458     return ret;
1459 }
1460 
1461 // The Iso/Mifare Xchg timeout in PN544 is a non-linear function over X
1462 // spanning 0 - 4.9s: timeout in seconds = (256 * 16 / 13560000) * 2 ^ X
1463 //
1464 // We keep the constant part of the formula in a static; note the factor
1465 // 1000 off, which is due to the fact that the formula calculates seconds,
1466 // but this method gets milliseconds as an argument.
1467 static double nxp_nfc_timeout_factor = (256 * 16) / 13560.0;
1468 
calcTimeout(int timeout_in_ms)1469 static int calcTimeout(int timeout_in_ms) {
1470    // timeout = (256 * 16 / 13560000) * 2 ^ X
1471    // First find the first X for which timeout > requested timeout
1472    return (log2(ceil(((double) timeout_in_ms) / nxp_nfc_timeout_factor)));
1473 }
1474 
setIsoDepTimeout(jint timeout)1475 static void setIsoDepTimeout(jint timeout) {
1476    if (timeout <= 4900) {
1477        int value = calcTimeout(timeout);
1478        // Then re-compute the actual timeout based on X
1479        double actual_timeout = nxp_nfc_timeout_factor * (1 << value);
1480        // Set the sw watchdog a bit longer (The PN544 timeout is very accurate,
1481        // but it will take some time to get back through the sw layers.
1482        // 500 ms should be enough).
1483        phLibNfc_SetHciTimeout(ceil(actual_timeout + 500));
1484        value |= 0x10; // bit 4 to enable timeout
1485        phLibNfc_SetIsoXchgTimeout(value);
1486    }
1487    else {
1488        // Also note that if we desire a timeout > 4.9s, the Iso Xchg timeout
1489        // must be disabled completely, to prevent the PN544 from aborting
1490        // the transaction. We reuse the HCI sw watchdog to catch the timeout
1491        // in that case.
1492        phLibNfc_SetIsoXchgTimeout(0x00);
1493        phLibNfc_SetHciTimeout(timeout);
1494    }
1495 }
1496 
setNfcATimeout(jint timeout)1497 static void setNfcATimeout(jint timeout) {
1498    if (timeout <= 4900) {
1499        int value = calcTimeout(timeout);
1500        phLibNfc_SetMifareRawTimeout(value);
1501    }
1502    else {
1503        // Disable mifare raw timeout, use HCI sw watchdog instead
1504        phLibNfc_SetMifareRawTimeout(0x00);
1505        phLibNfc_SetHciTimeout(timeout);
1506    }
1507 }
1508 
com_android_nfc_NfcManager_doSetTimeout(JNIEnv *,jobject,jint tech,jint timeout)1509 static bool com_android_nfc_NfcManager_doSetTimeout(JNIEnv*, jobject,
1510         jint tech, jint timeout) {
1511     bool success = false;
1512     CONCURRENCY_LOCK();
1513     if (timeout <= 0) {
1514         ALOGE("Timeout must be positive.");
1515         success = false;
1516     } else {
1517         switch (tech) {
1518             case TARGET_TYPE_MIFARE_CLASSIC:
1519             case TARGET_TYPE_MIFARE_UL:
1520                 // Intentional fall-through, Mifare UL, Classic
1521                 // transceive just uses raw 3A frames
1522             case TARGET_TYPE_ISO14443_3A:
1523                 setNfcATimeout(timeout);
1524                 success = true;
1525                 break;
1526             case TARGET_TYPE_ISO14443_4:
1527                 setIsoDepTimeout(timeout);
1528                 success = true;
1529                 break;
1530             case TARGET_TYPE_FELICA:
1531                 setFelicaTimeout(timeout);
1532                 success = true;
1533                 break;
1534             default:
1535                 ALOGW("doSetTimeout: Timeout not supported for tech %d", tech);
1536                 success = false;
1537         }
1538     }
1539     CONCURRENCY_UNLOCK();
1540     return success;
1541 }
1542 
com_android_nfc_NfcManager_doGetTimeout(JNIEnv *,jobject,jint tech)1543 static jint com_android_nfc_NfcManager_doGetTimeout(JNIEnv*, jobject,
1544         jint tech) {
1545     int timeout = -1;
1546     CONCURRENCY_LOCK();
1547     switch (tech) {
1548         case TARGET_TYPE_MIFARE_CLASSIC:
1549         case TARGET_TYPE_MIFARE_UL:
1550             // Intentional fall-through, Mifare UL, Classic
1551             // transceive just uses raw 3A frames
1552         case TARGET_TYPE_ISO14443_3A:
1553             timeout = phLibNfc_GetMifareRawTimeout();
1554             if (timeout == 0) {
1555                 timeout = phLibNfc_GetHciTimeout();
1556             } else {
1557                 // Timeout returned from libnfc needs conversion to ms
1558                 timeout = (nxp_nfc_timeout_factor * (1 << timeout));
1559             }
1560             break;
1561         case TARGET_TYPE_ISO14443_4:
1562             timeout = phLibNfc_GetIsoXchgTimeout() & 0x0F; // lower 4 bits only
1563             if (timeout == 0) {
1564                 timeout = phLibNfc_GetHciTimeout();
1565             } else {
1566                 // Timeout returned from libnfc needs conversion to ms
1567                 timeout = (nxp_nfc_timeout_factor * (1 << timeout));
1568             }
1569             break;
1570         case TARGET_TYPE_FELICA:
1571             timeout = phLibNfc_GetFelicaTimeout();
1572             if (timeout == 0) {
1573                 timeout = phLibNfc_GetHciTimeout();
1574             } else {
1575                 // Felica timeout already in ms
1576             }
1577             break;
1578         default:
1579             ALOGW("doGetTimeout: Timeout not supported for tech %d", tech);
1580             break;
1581     }
1582     CONCURRENCY_UNLOCK();
1583     return timeout;
1584 }
1585 
1586 
com_android_nfc_NfcManager_init_native_struc(JNIEnv * e,jobject o)1587 static jboolean com_android_nfc_NfcManager_init_native_struc(JNIEnv *e, jobject o)
1588 {
1589    NFCSTATUS status;
1590    struct nfc_jni_native_data *nat = NULL;
1591    jclass cls;
1592    jobject obj;
1593    jfieldID f;
1594 
1595    TRACE("******  Init Native Structure ******");
1596 
1597    /* Initialize native structure */
1598    nat = (nfc_jni_native_data*)malloc(sizeof(struct nfc_jni_native_data));
1599    if(nat == NULL)
1600    {
1601       ALOGD("malloc of nfc_jni_native_data failed");
1602       return FALSE;
1603    }
1604    memset(nat, 0, sizeof(*nat));
1605    e->GetJavaVM(&(nat->vm));
1606    nat->env_version = e->GetVersion();
1607    nat->manager = e->NewGlobalRef(o);
1608 
1609    cls = e->GetObjectClass(o);
1610    f = e->GetFieldID(cls, "mNative", "J");
1611    e->SetLongField(o, f, (jlong)nat);
1612 
1613    /* Initialize native cached references */
1614    cached_NfcManager_notifyNdefMessageListeners = e->GetMethodID(cls,
1615       "notifyNdefMessageListeners","(Lcom/android/nfc/dhimpl/NativeNfcTag;)V");
1616 
1617    cached_NfcManager_notifyLlcpLinkActivation = e->GetMethodID(cls,
1618       "notifyLlcpLinkActivation","(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V");
1619 
1620    cached_NfcManager_notifyLlcpLinkDeactivated = e->GetMethodID(cls,
1621       "notifyLlcpLinkDeactivated","(Lcom/android/nfc/dhimpl/NativeP2pDevice;)V");
1622 
1623    cached_NfcManager_notifyRfFieldActivated = e->GetMethodID(cls,
1624       "notifyRfFieldActivated", "()V");
1625 
1626    cached_NfcManager_notifyRfFieldDeactivated = e->GetMethodID(cls,
1627       "notifyRfFieldDeactivated", "()V");
1628 
1629    if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeNfcTag",&(nat->cached_NfcTag)) == -1)
1630    {
1631       ALOGD("Native Structure initialization failed");
1632       return FALSE;
1633    }
1634 
1635    if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeP2pDevice",&(nat->cached_P2pDevice)) == -1)
1636    {
1637       ALOGD("Native Structure initialization failed");
1638       return FALSE;
1639    }
1640    TRACE("****** Init Native Structure OK ******");
1641    return TRUE;
1642 
1643 }
1644 
1645 /* Init/Deinit method */
com_android_nfc_NfcManager_initialize(JNIEnv * e,jobject o)1646 static jboolean com_android_nfc_NfcManager_initialize(JNIEnv *e, jobject o)
1647 {
1648    struct nfc_jni_native_data *nat = NULL;
1649    int init_result = JNI_FALSE;
1650 #ifdef TNFC_EMULATOR_ONLY
1651    char value[PROPERTY_VALUE_MAX];
1652 #endif
1653    jboolean result;
1654 
1655    CONCURRENCY_LOCK();
1656 
1657 #ifdef TNFC_EMULATOR_ONLY
1658    if (!property_get("ro.kernel.qemu", value, 0))
1659    {
1660       ALOGE("NFC Initialization failed: not running in an emulator\n");
1661       goto clean_and_return;
1662    }
1663 #endif
1664 
1665    /* Retrieve native structure address */
1666    nat = nfc_jni_get_nat(e, o);
1667 
1668    nat->seId = SMX_SECURE_ELEMENT_ID;
1669 
1670    nat->lto = 150;  // LLCP_LTO
1671    nat->miu = 128; // LLCP_MIU
1672    // WKS indicates well-known services; 1 << sap for each supported SAP.
1673    // We support Link mgmt (SAP 0), SDP (SAP 1) and SNEP (SAP 4)
1674    nat->wks = 0x13;  // LLCP_WKS
1675    nat->opt = 0;  // LLCP_OPT
1676    nat->p2p_initiator_modes = phNfc_eP2P_ALL;
1677    nat->p2p_target_modes = 0x0E; // All passive except 106, active
1678    nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443A = TRUE;
1679    nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso14443B = TRUE;
1680    nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica212 = TRUE;
1681    nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableFelica424 = TRUE;
1682    nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableIso15693 = TRUE;
1683    nat->discovery_cfg.PollDevInfo.PollCfgInfo.EnableNfcActive = TRUE;
1684    nat->discovery_cfg.PollDevInfo.PollCfgInfo.DisableCardEmulation = FALSE;
1685 
1686    nat->registry_info.MifareUL = TRUE;
1687    nat->registry_info.MifareStd = TRUE;
1688    nat->registry_info.ISO14443_4A = TRUE;
1689    nat->registry_info.ISO14443_4B = TRUE;
1690    nat->registry_info.Jewel = TRUE;
1691    nat->registry_info.Felica = TRUE;
1692    nat->registry_info.NFC = TRUE;
1693    nat->registry_info.ISO15693 = TRUE;
1694 
1695    exported_nat = nat;
1696 
1697    /* Perform the initialization */
1698    init_result = nfc_jni_initialize(nat);
1699 
1700 clean_and_return:
1701    CONCURRENCY_UNLOCK();
1702 
1703    /* Convert the result and return */
1704    return (init_result==TRUE)?JNI_TRUE:JNI_FALSE;
1705 }
1706 
com_android_nfc_NfcManager_deinitialize(JNIEnv * e,jobject o)1707 static jboolean com_android_nfc_NfcManager_deinitialize(JNIEnv *e, jobject o)
1708 {
1709    struct timespec ts;
1710    NFCSTATUS status;
1711    int result = JNI_FALSE;
1712    struct nfc_jni_native_data *nat;
1713    int bStackReset = FALSE;
1714    struct nfc_jni_callback_data cb_data;
1715 
1716    CONCURRENCY_LOCK();
1717 
1718    /* Retrieve native structure address */
1719    nat = nfc_jni_get_nat(e, o);
1720 
1721    /* Clear previous configuration */
1722    memset(&nat->discovery_cfg, 0, sizeof(phLibNfc_sADD_Cfg_t));
1723    memset(&nat->registry_info, 0, sizeof(phLibNfc_Registry_Info_t));
1724 
1725    /* Create the local semaphore */
1726    if (nfc_cb_data_init(&cb_data, NULL))
1727    {
1728       TRACE("phLibNfc_Mgt_DeInitialize()");
1729       REENTRANCE_LOCK();
1730       status = phLibNfc_Mgt_DeInitialize(gHWRef, nfc_jni_deinit_callback, (void *)&cb_data);
1731       REENTRANCE_UNLOCK();
1732       if (status == NFCSTATUS_PENDING)
1733       {
1734          TRACE("phLibNfc_Mgt_DeInitialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
1735 
1736          clock_gettime(CLOCK_REALTIME, &ts);
1737          ts.tv_sec += 5;
1738 
1739          /* Wait for callback response */
1740          if(sem_timedwait(&cb_data.sem, &ts) == -1)
1741          {
1742             ALOGW("Operation timed out");
1743             bStackReset = TRUE;
1744          }
1745 
1746          if(cb_data.status != NFCSTATUS_SUCCESS)
1747          {
1748             ALOGE("Failed to deinit the stack");
1749             bStackReset = TRUE;
1750          }
1751       }
1752       else
1753       {
1754          TRACE("phLibNfc_Mgt_DeInitialize() returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
1755          bStackReset = TRUE;
1756       }
1757       nfc_cb_data_deinit(&cb_data);
1758    }
1759    else
1760    {
1761        ALOGE("Failed to create semaphore (errno=0x%08x)", errno);
1762        bStackReset = TRUE;
1763    }
1764 
1765    kill_client(nat);
1766 
1767    if(bStackReset == TRUE)
1768    {
1769       /* Complete deinit. failed, try hard restart of NFC */
1770       ALOGW("Reseting stack...");
1771       emergency_recovery(nat);
1772    }
1773 
1774    result = nfc_jni_unconfigure_driver(nat);
1775 
1776    TRACE("NFC Deinitialized");
1777 
1778    CONCURRENCY_UNLOCK();
1779 
1780    return TRUE;
1781 }
1782 
1783 /* Llcp methods */
1784 
com_android_nfc_NfcManager_doCheckLlcp(JNIEnv * e,jobject o)1785 static jboolean com_android_nfc_NfcManager_doCheckLlcp(JNIEnv *e, jobject o)
1786 {
1787    NFCSTATUS ret;
1788    bool freeData = false;
1789    jboolean result = JNI_FALSE;
1790    struct nfc_jni_native_data *nat;
1791    struct nfc_jni_callback_data  *cb_data;
1792 
1793 
1794    CONCURRENCY_LOCK();
1795 
1796    /* Memory allocation for cb_data
1797     * This is on the heap because it is used by libnfc
1798     * even after this call has succesfully finished. It is only freed
1799     * upon link closure in nfc_jni_llcp_linkStatus_callback.
1800     */
1801    cb_data = (struct nfc_jni_callback_data*) malloc (sizeof(nfc_jni_callback_data));
1802 
1803    /* Retrieve native structure address */
1804    nat = nfc_jni_get_nat(e, o);
1805 
1806    /* Create the local semaphore */
1807    if (!nfc_cb_data_init(cb_data, (void*)nat))
1808    {
1809       goto clean_and_return;
1810    }
1811 
1812    /* Check LLCP compliancy */
1813    TRACE("phLibNfc_Llcp_CheckLlcp(hLlcpHandle=0x%08x)", hLlcpHandle);
1814    REENTRANCE_LOCK();
1815    ret = phLibNfc_Llcp_CheckLlcp(hLlcpHandle,
1816                                  nfc_jni_checkLlcp_callback,
1817                                  nfc_jni_llcp_linkStatus_callback,
1818                                  (void*)cb_data);
1819    REENTRANCE_UNLOCK();
1820    /* In case of a NFCIP return NFCSTATUS_SUCCESS and in case of an another protocol
1821     * NFCSTATUS_PENDING. In this case NFCSTATUS_SUCCESS will also cause the callback. */
1822    if(ret != NFCSTATUS_PENDING && ret != NFCSTATUS_SUCCESS)
1823    {
1824       ALOGE("phLibNfc_Llcp_CheckLlcp() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1825       freeData = true;
1826       goto clean_and_return;
1827    }
1828    TRACE("phLibNfc_Llcp_CheckLlcp() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1829 
1830    /* Wait for callback response */
1831    if(sem_wait(&cb_data->sem))
1832    {
1833       ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
1834       goto clean_and_return;
1835    }
1836 
1837    if(cb_data->status == NFCSTATUS_SUCCESS)
1838    {
1839       result = JNI_TRUE;
1840    }
1841 
1842 clean_and_return:
1843    nfc_cb_data_deinit(cb_data);
1844    if (freeData) {
1845        free(cb_data);
1846    }
1847    CONCURRENCY_UNLOCK();
1848    return result;
1849 }
1850 
com_android_nfc_NfcManager_doActivateLlcp(JNIEnv *,jobject)1851 static jboolean com_android_nfc_NfcManager_doActivateLlcp(JNIEnv*, jobject)
1852 {
1853    NFCSTATUS ret;
1854    TRACE("phLibNfc_Llcp_Activate(hRemoteDevice=0x%08x)", hLlcpHandle);
1855    REENTRANCE_LOCK();
1856    ret = phLibNfc_Llcp_Activate(hLlcpHandle);
1857    REENTRANCE_UNLOCK();
1858    if(ret == NFCSTATUS_SUCCESS)
1859    {
1860       TRACE("phLibNfc_Llcp_Activate() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1861       return JNI_TRUE;
1862    }
1863    else
1864    {
1865       ALOGE("phLibNfc_Llcp_Activate() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1866       return JNI_FALSE;
1867    }
1868 }
1869 
1870 
1871 
com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket(JNIEnv * e,jobject o,jint nSap,jstring sn)1872 static jobject com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket(JNIEnv *e, jobject o,
1873         jint nSap, jstring sn)
1874 {
1875    NFCSTATUS ret;
1876    jobject connectionlessSocket = NULL;
1877    phLibNfc_Handle hLlcpSocket;
1878    struct nfc_jni_native_data *nat;
1879    phNfc_sData_t sWorkingBuffer = {NULL, 0};
1880    phNfc_sData_t serviceName = {NULL, 0};
1881    phLibNfc_Llcp_sLinkParameters_t sParams;
1882    jclass clsNativeConnectionlessSocket;
1883    jfieldID f;
1884 
1885    /* Retrieve native structure address */
1886    nat = nfc_jni_get_nat(e, o);
1887 
1888    /* Allocate Working buffer length */
1889    phLibNfc_Llcp_GetLocalInfo(hLlcpHandle, &sParams);
1890    sWorkingBuffer.length = sParams.miu + 1; // extra byte for SAP
1891    sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length);
1892 
1893    /* Create socket */
1894    TRACE("phLibNfc_Llcp_Socket(eType=phFriNfc_LlcpTransport_eConnectionLess, ...)");
1895    REENTRANCE_LOCK();
1896    ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionLess,
1897                               NULL,
1898                               &sWorkingBuffer,
1899                               &hLlcpSocket,
1900                               nfc_jni_llcp_transport_socket_err_callback,
1901                               (void*)nat);
1902    REENTRANCE_UNLOCK();
1903 
1904    if(ret != NFCSTATUS_SUCCESS)
1905    {
1906       lastErrorStatus = ret;
1907       ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1908       goto error;
1909    }
1910    TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1911 
1912    /* Service socket */
1913    if (sn == NULL) {
1914        serviceName.buffer = NULL;
1915        serviceName.length = 0;
1916    } else {
1917        serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL);
1918        serviceName.length = (uint32_t)e->GetStringUTFLength(sn);
1919    }
1920 
1921    /* Bind socket */
1922    TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap);
1923    REENTRANCE_LOCK();
1924    ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, &serviceName);
1925    REENTRANCE_UNLOCK();
1926    if(ret != NFCSTATUS_SUCCESS)
1927    {
1928       lastErrorStatus = ret;
1929       ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1930       /* Close socket created */
1931       REENTRANCE_LOCK();
1932       ret = phLibNfc_Llcp_Close(hLlcpSocket);
1933       REENTRANCE_UNLOCK();
1934       goto error;
1935    }
1936    TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
1937 
1938 
1939    /* Create new NativeLlcpConnectionlessSocket object */
1940    if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpConnectionlessSocket",&(connectionlessSocket)) == -1)
1941    {
1942       goto error;
1943    }
1944 
1945    /* Get NativeConnectionless class object */
1946    clsNativeConnectionlessSocket = e->GetObjectClass(connectionlessSocket);
1947    if(e->ExceptionCheck())
1948    {
1949       goto error;
1950    }
1951 
1952    /* Set socket handle */
1953    f = e->GetFieldID(clsNativeConnectionlessSocket, "mHandle", "I");
1954    e->SetIntField(connectionlessSocket, f,(jint)hLlcpSocket);
1955    TRACE("Connectionless socket Handle = %02x\n",hLlcpSocket);
1956 
1957    /* Set the miu link of the connectionless socket */
1958    f = e->GetFieldID(clsNativeConnectionlessSocket, "mLinkMiu", "I");
1959    e->SetIntField(connectionlessSocket, f,(jint)PHFRINFC_LLCP_MIU_DEFAULT);
1960    TRACE("Connectionless socket Link MIU = %d\n",PHFRINFC_LLCP_MIU_DEFAULT);
1961 
1962    /* Set socket SAP */
1963    f = e->GetFieldID(clsNativeConnectionlessSocket, "mSap", "I");
1964    e->SetIntField(connectionlessSocket, f,(jint)nSap);
1965    TRACE("Connectionless socket SAP = %d\n",nSap);
1966 
1967    return connectionlessSocket;
1968 error:
1969    if (serviceName.buffer != NULL) {
1970       e->ReleaseStringUTFChars(sn, (const char *)serviceName.buffer);
1971    }
1972 
1973    if (sWorkingBuffer.buffer != NULL) {
1974        free(sWorkingBuffer.buffer);
1975    }
1976 
1977    return NULL;
1978 }
1979 
com_android_nfc_NfcManager_doCreateLlcpServiceSocket(JNIEnv * e,jobject o,jint nSap,jstring sn,jint miu,jint rw,jint linearBufferLength)1980 static jobject com_android_nfc_NfcManager_doCreateLlcpServiceSocket(JNIEnv *e, jobject o, jint nSap, jstring sn, jint miu, jint rw, jint linearBufferLength)
1981 {
1982    NFCSTATUS ret;
1983    phLibNfc_Handle hLlcpSocket;
1984    phLibNfc_Llcp_sSocketOptions_t sOptions;
1985    phNfc_sData_t sWorkingBuffer;
1986    phNfc_sData_t serviceName;
1987    struct nfc_jni_native_data *nat;
1988    jobject serviceSocket = NULL;
1989    jclass clsNativeLlcpServiceSocket;
1990    jfieldID f;
1991 
1992    /* Retrieve native structure address */
1993    nat = nfc_jni_get_nat(e, o);
1994 
1995    /* Set Connection Oriented socket options */
1996    sOptions.miu = miu;
1997    sOptions.rw  = rw;
1998 
1999    /* Allocate Working buffer length */
2000    sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength;
2001    sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length);
2002 
2003 
2004    /* Create socket */
2005    TRACE("phLibNfc_Llcp_Socket(hRemoteDevice=0x%08x, eType=phFriNfc_LlcpTransport_eConnectionOriented, ...)", hLlcpHandle);
2006    REENTRANCE_LOCK();
2007    ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionOriented,
2008                               &sOptions,
2009                               &sWorkingBuffer,
2010                               &hLlcpSocket,
2011                               nfc_jni_llcp_transport_socket_err_callback,
2012                               (void*)nat);
2013    REENTRANCE_UNLOCK();
2014 
2015    if(ret != NFCSTATUS_SUCCESS)
2016    {
2017       ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2018       lastErrorStatus = ret;
2019       goto error;
2020    }
2021    TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2022 
2023    /* Service socket */
2024    if (sn == NULL) {
2025        serviceName.buffer = NULL;
2026        serviceName.length = 0;
2027    } else {
2028        serviceName.buffer = (uint8_t*)e->GetStringUTFChars(sn, NULL);
2029        serviceName.length = (uint32_t)e->GetStringUTFLength(sn);
2030    }
2031 
2032    /* Bind socket */
2033    TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap);
2034    REENTRANCE_LOCK();
2035    ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, &serviceName);
2036    REENTRANCE_UNLOCK();
2037    if(ret != NFCSTATUS_SUCCESS)
2038    {
2039       lastErrorStatus = ret;
2040       ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2041       /* Close socket created */
2042       ret = phLibNfc_Llcp_Close(hLlcpSocket);
2043       goto error;
2044    }
2045    TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2046 
2047    TRACE("phLibNfc_Llcp_Listen(hSocket=0x%08x, ...)", hLlcpSocket);
2048    REENTRANCE_LOCK();
2049    ret = phLibNfc_Llcp_Listen( hLlcpSocket,
2050                                nfc_jni_llcp_transport_listen_socket_callback,
2051                                (void*)hLlcpSocket);
2052    REENTRANCE_UNLOCK();
2053 
2054    if(ret != NFCSTATUS_SUCCESS)
2055    {
2056       ALOGE("phLibNfc_Llcp_Listen() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2057       lastErrorStatus = ret;
2058       /* Close created socket */
2059       REENTRANCE_LOCK();
2060       ret = phLibNfc_Llcp_Close(hLlcpSocket);
2061       REENTRANCE_UNLOCK();
2062       goto error;
2063    }
2064    TRACE("phLibNfc_Llcp_Listen() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2065 
2066    /* Create new NativeLlcpServiceSocket object */
2067    if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpServiceSocket",&(serviceSocket)) == -1)
2068    {
2069       ALOGE("Llcp Socket object creation error");
2070       goto error;
2071    }
2072 
2073    /* Get NativeLlcpServiceSocket class object */
2074    clsNativeLlcpServiceSocket = e->GetObjectClass(serviceSocket);
2075    if(e->ExceptionCheck())
2076    {
2077       ALOGE("Llcp Socket get object class error");
2078       goto error;
2079    }
2080 
2081    /* Set socket handle */
2082    f = e->GetFieldID(clsNativeLlcpServiceSocket, "mHandle", "I");
2083    e->SetIntField(serviceSocket, f,(jint)hLlcpSocket);
2084    TRACE("Service socket Handle = %02x\n",hLlcpSocket);
2085 
2086    /* Set socket linear buffer length */
2087    f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalLinearBufferLength", "I");
2088    e->SetIntField(serviceSocket, f,(jint)linearBufferLength);
2089    TRACE("Service socket Linear buffer length = %02x\n",linearBufferLength);
2090 
2091    /* Set socket MIU */
2092    f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalMiu", "I");
2093    e->SetIntField(serviceSocket, f,(jint)miu);
2094    TRACE("Service socket MIU = %d\n",miu);
2095 
2096    /* Set socket RW */
2097    f = e->GetFieldID(clsNativeLlcpServiceSocket, "mLocalRw", "I");
2098    e->SetIntField(serviceSocket, f,(jint)rw);
2099    TRACE("Service socket RW = %d\n",rw);
2100 
2101    return serviceSocket;
2102 error:
2103    if (serviceName.buffer != NULL) {
2104       e->ReleaseStringUTFChars(sn, (const char *)serviceName.buffer);
2105    }
2106    return NULL;
2107 }
2108 
com_android_nfc_NfcManager_doCreateLlcpSocket(JNIEnv * e,jobject o,jint nSap,jint miu,jint rw,jint linearBufferLength)2109 static jobject com_android_nfc_NfcManager_doCreateLlcpSocket(JNIEnv *e, jobject o, jint nSap, jint miu, jint rw, jint linearBufferLength)
2110 {
2111    jobject clientSocket = NULL;
2112    NFCSTATUS ret;
2113    phLibNfc_Handle hLlcpSocket;
2114    phLibNfc_Llcp_sSocketOptions_t sOptions;
2115    phNfc_sData_t sWorkingBuffer;
2116    struct nfc_jni_native_data *nat;
2117    jclass clsNativeLlcpSocket;
2118    jfieldID f;
2119 
2120    /* Retrieve native structure address */
2121    nat = nfc_jni_get_nat(e, o);
2122 
2123    /* Set Connection Oriented socket options */
2124    sOptions.miu = miu;
2125    sOptions.rw  = rw;
2126 
2127    /* Allocate Working buffer length */
2128    sWorkingBuffer.length = (miu*rw)+ miu + linearBufferLength;
2129    sWorkingBuffer.buffer = (uint8_t*)malloc(sWorkingBuffer.length);
2130 
2131    /* Create socket */
2132    TRACE("phLibNfc_Llcp_Socket(eType=phFriNfc_LlcpTransport_eConnectionOriented, ...)");
2133    REENTRANCE_LOCK();
2134    ret = phLibNfc_Llcp_Socket(phFriNfc_LlcpTransport_eConnectionOriented,
2135                               &sOptions,
2136                               &sWorkingBuffer,
2137                               &hLlcpSocket,
2138                               nfc_jni_llcp_transport_socket_err_callback,
2139                               (void*)nat);
2140    REENTRANCE_UNLOCK();
2141 
2142    if(ret != NFCSTATUS_SUCCESS)
2143    {
2144       ALOGE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2145       lastErrorStatus = ret;
2146       return NULL;
2147    }
2148    TRACE("phLibNfc_Llcp_Socket() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2149 
2150    /* Create new NativeLlcpSocket object */
2151    if(nfc_jni_cache_object(e,"com/android/nfc/dhimpl/NativeLlcpSocket",&(clientSocket)) == -1)
2152    {
2153       ALOGE("Llcp socket object creation error");
2154       return NULL;
2155    }
2156 
2157    /* Get NativeConnectionless class object */
2158    clsNativeLlcpSocket = e->GetObjectClass(clientSocket);
2159    if(e->ExceptionCheck())
2160    {
2161       ALOGE("Get class object error");
2162       return NULL;
2163    }
2164 
2165    /* Test if an SAP number is present */
2166    if(nSap != 0)
2167    {
2168       /* Bind socket */
2169       TRACE("phLibNfc_Llcp_Bind(hSocket=0x%08x, nSap=0x%02x)", hLlcpSocket, nSap);
2170       REENTRANCE_LOCK();
2171       ret = phLibNfc_Llcp_Bind(hLlcpSocket,nSap, NULL);
2172       REENTRANCE_UNLOCK();
2173       if(ret != NFCSTATUS_SUCCESS)
2174       {
2175          lastErrorStatus = ret;
2176          ALOGE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2177          /* Close socket created */
2178          REENTRANCE_LOCK();
2179          ret = phLibNfc_Llcp_Close(hLlcpSocket);
2180          REENTRANCE_UNLOCK();
2181          return NULL;
2182       }
2183       TRACE("phLibNfc_Llcp_Bind() returned 0x%04x[%s]", ret, nfc_jni_get_status_name(ret));
2184 
2185       /* Set socket SAP */
2186       f = e->GetFieldID(clsNativeLlcpSocket, "mSap", "I");
2187       e->SetIntField(clientSocket, f,(jint)nSap);
2188       TRACE("socket SAP = %d\n",nSap);
2189    }
2190 
2191    /* Set socket handle */
2192    f = e->GetFieldID(clsNativeLlcpSocket, "mHandle", "I");
2193    e->SetIntField(clientSocket, f,(jint)hLlcpSocket);
2194    TRACE("socket Handle = %02x\n",hLlcpSocket);
2195 
2196    /* Set socket MIU */
2197    f = e->GetFieldID(clsNativeLlcpSocket, "mLocalMiu", "I");
2198    e->SetIntField(clientSocket, f,(jint)miu);
2199    TRACE("socket MIU = %d\n",miu);
2200 
2201    /* Set socket RW */
2202    f = e->GetFieldID(clsNativeLlcpSocket, "mLocalRw", "I");
2203    e->SetIntField(clientSocket, f,(jint)rw);
2204    TRACE("socket RW = %d\n",rw);
2205 
2206 
2207    return clientSocket;
2208 }
2209 
com_android_nfc_NfcManager_doGetLastError(JNIEnv *,jobject)2210 static jint com_android_nfc_NfcManager_doGetLastError(JNIEnv*, jobject)
2211 {
2212    TRACE("Last Error Status = 0x%02x",lastErrorStatus);
2213 
2214    if(lastErrorStatus == NFCSTATUS_BUFFER_TOO_SMALL)
2215    {
2216       return ERROR_BUFFER_TOO_SMALL;
2217    }
2218    else if(lastErrorStatus == NFCSTATUS_INSUFFICIENT_RESOURCES)
2219    {
2220       return  ERROR_INSUFFICIENT_RESOURCES;
2221    }
2222    else
2223    {
2224       return lastErrorStatus;
2225    }
2226 }
2227 
com_android_nfc_NfcManager_doAbort(JNIEnv *,jobject)2228 static void com_android_nfc_NfcManager_doAbort(JNIEnv*, jobject)
2229 {
2230     emergency_recovery(NULL);
2231 }
2232 
com_android_nfc_NfcManager_doSetP2pInitiatorModes(JNIEnv * e,jobject o,jint modes)2233 static void com_android_nfc_NfcManager_doSetP2pInitiatorModes(JNIEnv *e, jobject o,
2234         jint modes)
2235 {
2236     ALOGE("Setting init modes to %x", modes);
2237     struct nfc_jni_native_data *nat = NULL;
2238     nat = nfc_jni_get_nat(e, o);
2239     nat->p2p_initiator_modes = modes;
2240 }
2241 
com_android_nfc_NfcManager_doSetP2pTargetModes(JNIEnv * e,jobject o,jint modes)2242 static void com_android_nfc_NfcManager_doSetP2pTargetModes(JNIEnv *e, jobject o,
2243         jint modes)
2244 {
2245     ALOGE("Setting target modes to %x", modes);
2246     struct nfc_jni_native_data *nat = NULL;
2247     nat = nfc_jni_get_nat(e, o);
2248     nat->p2p_target_modes = modes;
2249 }
2250 
performDownload(struct nfc_jni_native_data * nat,bool takeLock)2251 static bool performDownload(struct nfc_jni_native_data* nat, bool takeLock) {
2252     bool result = FALSE;
2253     int load_result;
2254     bool wasDisabled = FALSE;
2255     uint8_t OutputBuffer[1];
2256     uint8_t InputBuffer[1];
2257     NFCSTATUS status = NFCSTATUS_FAILED;
2258     struct nfc_jni_callback_data cb_data;
2259 
2260     /* Create the local semaphore */
2261     if (!nfc_cb_data_init(&cb_data, NULL))
2262     {
2263        result = FALSE;
2264        goto clean_and_return;
2265     }
2266 
2267     if (takeLock)
2268     {
2269         CONCURRENCY_LOCK();
2270     }
2271 
2272     /* Initialize Driver */
2273     if(!driverConfigured)
2274     {
2275         result = nfc_jni_configure_driver(nat);
2276         wasDisabled = TRUE;
2277     }
2278     TRACE("com_android_nfc_NfcManager_doDownload()");
2279 
2280     TRACE("Go in Download Mode");
2281     phLibNfc_Download_Mode();
2282 
2283     TRACE("Load new Firmware Image");
2284     load_result = phLibNfc_Load_Firmware_Image();
2285     if(load_result != 0)
2286     {
2287         TRACE("Load new Firmware Image - status = %d",load_result);
2288         result = FALSE;
2289         goto clean_and_return;
2290     }
2291 
2292     // Download
2293     gInputParam.buffer  = InputBuffer;
2294     gInputParam.length  = 0x01;
2295     gOutputParam.buffer = OutputBuffer;
2296     gOutputParam.length = 0x01;
2297 
2298     ALOGD("Download new Firmware");
2299     REENTRANCE_LOCK();
2300     status = phLibNfc_Mgt_IoCtl(gHWRef,NFC_FW_DOWNLOAD, &gInputParam, &gOutputParam, nfc_jni_ioctl_callback, (void *)&cb_data);
2301     REENTRANCE_UNLOCK();
2302     if(status != NFCSTATUS_PENDING)
2303     {
2304         ALOGE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
2305         result = FALSE;
2306         goto clean_and_return;
2307     }
2308     TRACE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
2309 
2310     /* Wait for callback response */
2311     if(sem_wait(&cb_data.sem))
2312     {
2313        ALOGE("Failed to wait for semaphore (errno=0x%08x)", errno);
2314        result = FALSE;
2315        goto clean_and_return;
2316     }
2317 
2318     /* NOTE: we will get NFCSTATUS_FEATURE_NOT_SUPPORTED when we
2319        try to download an old-style firmware on top of a new-style
2320        firmware.  Hence, this is expected behavior, and not an
2321        error condition. */
2322     if(cb_data.status != NFCSTATUS_SUCCESS && cb_data.status != NFCSTATUS_FEATURE_NOT_SUPPORTED)
2323     {
2324         TRACE("phLibNfc_Mgt_IoCtl() (download) returned 0x%04x[%s]", status, nfc_jni_get_status_name(status));
2325         result = FALSE;
2326         goto clean_and_return;
2327     }
2328 
2329     if(cb_data.status == NFCSTATUS_FEATURE_NOT_SUPPORTED)
2330     {
2331         ALOGW("Old-style firmware not installed on top of new-style firmware. Using existing firmware in the chip.");
2332     }
2333 
2334     /*Download is successful*/
2335     result = TRUE;
2336 clean_and_return:
2337     TRACE("phLibNfc_HW_Reset()");
2338     phLibNfc_HW_Reset();
2339     /* Deinitialize Driver */
2340     if(wasDisabled)
2341     {
2342         result = nfc_jni_unconfigure_driver(nat);
2343     }
2344     if (takeLock)
2345     {
2346         CONCURRENCY_UNLOCK();
2347     }
2348     nfc_cb_data_deinit(&cb_data);
2349     return result;
2350 }
2351 
com_android_nfc_NfcManager_doDownload(JNIEnv * e,jobject o)2352 static jboolean com_android_nfc_NfcManager_doDownload(JNIEnv *e, jobject o)
2353 {
2354     struct nfc_jni_native_data *nat = NULL;
2355     nat = nfc_jni_get_nat(e, o);
2356     return performDownload(nat, true);
2357 }
2358 
com_android_nfc_NfcManager_doDump(JNIEnv * e,jobject)2359 static jstring com_android_nfc_NfcManager_doDump(JNIEnv *e, jobject)
2360 {
2361     char buffer[100];
2362     snprintf(buffer, sizeof(buffer), "libnfc llc error_count=%u", libnfc_llc_error_count);
2363     return e->NewStringUTF(buffer);
2364 }
2365 
2366 /*
2367  * JNI registration.
2368  */
2369 static JNINativeMethod gMethods[] =
2370 {
2371    {"doDownload", "()Z",
2372         (void *)com_android_nfc_NfcManager_doDownload},
2373 
2374    {"initializeNativeStructure", "()Z",
2375       (void *)com_android_nfc_NfcManager_init_native_struc},
2376 
2377    {"doInitialize", "()Z",
2378       (void *)com_android_nfc_NfcManager_initialize},
2379 
2380    {"doDeinitialize", "()Z",
2381       (void *)com_android_nfc_NfcManager_deinitialize},
2382 
2383    {"doEnableDiscovery", "(IZZZZ)V",
2384       (void *)com_android_nfc_NfcManager_enableDiscovery},
2385 
2386    {"doCheckLlcp", "()Z",
2387       (void *)com_android_nfc_NfcManager_doCheckLlcp},
2388 
2389    {"doActivateLlcp", "()Z",
2390       (void *)com_android_nfc_NfcManager_doActivateLlcp},
2391 
2392    {"doCreateLlcpConnectionlessSocket", "(ILjava/lang/String;)Lcom/android/nfc/dhimpl/NativeLlcpConnectionlessSocket;",
2393       (void *)com_android_nfc_NfcManager_doCreateLlcpConnectionlessSocket},
2394 
2395    {"doCreateLlcpServiceSocket", "(ILjava/lang/String;III)Lcom/android/nfc/dhimpl/NativeLlcpServiceSocket;",
2396       (void *)com_android_nfc_NfcManager_doCreateLlcpServiceSocket},
2397 
2398    {"doCreateLlcpSocket", "(IIII)Lcom/android/nfc/dhimpl/NativeLlcpSocket;",
2399       (void *)com_android_nfc_NfcManager_doCreateLlcpSocket},
2400 
2401    {"doGetLastError", "()I",
2402       (void *)com_android_nfc_NfcManager_doGetLastError},
2403 
2404    {"disableDiscovery", "()V",
2405       (void *)com_android_nfc_NfcManager_disableDiscovery},
2406 
2407    {"doSetTimeout", "(II)Z",
2408       (void *)com_android_nfc_NfcManager_doSetTimeout},
2409 
2410    {"doGetTimeout", "(I)I",
2411       (void *)com_android_nfc_NfcManager_doGetTimeout},
2412 
2413    {"doResetTimeouts", "()V",
2414       (void *)com_android_nfc_NfcManager_doResetTimeouts},
2415 
2416    {"doAbort", "()V",
2417       (void *)com_android_nfc_NfcManager_doAbort},
2418 
2419    {"doSetP2pInitiatorModes","(I)V",
2420       (void *)com_android_nfc_NfcManager_doSetP2pInitiatorModes},
2421 
2422    {"doSetP2pTargetModes","(I)V",
2423       (void *)com_android_nfc_NfcManager_doSetP2pTargetModes},
2424 
2425    {"doDump", "()Ljava/lang/String;",
2426       (void *)com_android_nfc_NfcManager_doDump},
2427 };
2428 
2429 
register_com_android_nfc_NativeNfcManager(JNIEnv * e)2430 int register_com_android_nfc_NativeNfcManager(JNIEnv *e)
2431 {
2432     nfc_jni_native_monitor_t *nfc_jni_native_monitor;
2433 
2434    nfc_jni_native_monitor = nfc_jni_init_monitor();
2435    if(nfc_jni_native_monitor == NULL)
2436    {
2437       ALOGE("NFC Manager cannot recover native monitor %x\n", errno);
2438       return -1;
2439    }
2440 
2441    return jniRegisterNativeMethods(e,
2442       "com/android/nfc/dhimpl/NativeNfcManager",
2443       gMethods, NELEM(gMethods));
2444 }
2445 
2446 } /* namespace android */
2447