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